Search code examples
javamultithreadingjavafxfreezeopenjfx

Java fx program freezes


This is probably a bug in java fx, I might file a report but I want to first find out more about it because to my experience a bug that does not provide a way to reproduce is not gonna be lokked at. Also I really badly want a work arround for it.

So the freeze happens randomly and probably ever 15th time I open the program. It mostly happens at the start of the programm. The programm is this, uses java 11 and openjfx 11. The freezes happen on Windows(maybe on Unix as well who knows).

The java application thread waits for the render to finish but the render never finishes(probably runs in circles here). enter image description here

Following is the thread dump of the Render-Thread that seems to run in circles:

QuantumRenderer-0  Runnable CPU usage on sample: 1s
  com.sun.marlin.DHelpers.subdivideAt(double, double[], int, double[], int, double[], int, int) DHelpers.java:419
  com.sun.marlin.DDasher.somethingTo(int) DDasher.java:410
  com.sun.marlin.DDasher.curveTo(double, double, double, double, double, double) DDasher.java:749
  com.sun.prism.impl.shape.DMarlinPrismUtils.feedConsumer(DRendererContext, Path2D, BaseTransform, DPathConsumer2D) DMarlinPrismUtils.java:561
  com.sun.prism.impl.shape.DMarlinPrismUtils.setupRenderer(DRendererContext, Shape, BasicStroke, BaseTransform, Rectangle, boolean) DMarlinPrismUtils.java:286
  com.sun.prism.impl.shape.DMarlinRasterizer.getMaskData(Shape, BasicStroke, RectBounds, BaseTransform, boolean, boolean) DMarlinRasterizer.java:86
  com.sun.prism.impl.shape.ShapeUtil.rasterizeShape(Shape, BasicStroke, RectBounds, BaseTransform, boolean, boolean) ShapeUtil.java:64
  com.sun.prism.impl.ps.BaseShaderGraphics.renderShape(Shape, BasicStroke, float, float, float, float) BaseShaderGraphics.java:463
  com.sun.prism.impl.BaseGraphics.draw(Shape) BaseGraphics.java:402
  com.sun.javafx.webkit.prism.WCGraphicsPrismContext$17.doPaint(Graphics) WCGraphicsPrismContext.java:1761
  com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(Graphics) WCGraphicsPrismContext.java:1512
  com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint() WCGraphicsPrismContext.java:1497
  com.sun.javafx.webkit.prism.WCGraphicsPrismContext.strokePath(WCPath) WCGraphicsPrismContext.java:1764
  com.sun.webkit.graphics.GraphicsDecoder.decode(WCGraphicsManager, WCGraphicsContext, BufferData) GraphicsDecoder.java:278
  com.sun.webkit.graphics.WCRenderQueue.decode(WCGraphicsContext) WCRenderQueue.java:92
  com.sun.webkit.WebPage.paint2GC(WCGraphicsContext) WebPage.java:734
  com.sun.webkit.WebPage.paint(WCGraphicsContext, int, int, int, int) WebPage.java:701
  com.sun.javafx.sg.prism.web.NGWebView.renderContent(Graphics) NGWebView.java:96
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.renderForClip(Graphics) NGNode.java:2313
  com.sun.javafx.sg.prism.NGNode.renderRectClip(Graphics, NGRectangle) NGNode.java:2207
  com.sun.javafx.sg.prism.NGNode.renderClip(Graphics) NGNode.java:2233
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2066
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.sg.prism.NGGroup.renderContent(Graphics) NGGroup.java:270
  com.sun.javafx.sg.prism.NGRegion.renderContent(Graphics) NGRegion.java:578
  com.sun.javafx.sg.prism.NGNode.doRender(Graphics) NGNode.java:2072
  com.sun.javafx.sg.prism.NGNode.render(Graphics) NGNode.java:1964
  com.sun.javafx.tk.quantum.ViewPainter.doPaint(Graphics, NodePath) ViewPainter.java:479
  com.sun.javafx.tk.quantum.ViewPainter.paintImpl(Graphics) ViewPainter.java:328
  com.sun.javafx.tk.quantum.PresentingPainter.run() PresentingPainter.java:91
  java.util.concurrent.Executors$RunnableAdapter.call() Executors.java:514
  java.util.concurrent.FutureTask.runAndReset() FutureTask.java:305
  com.sun.javafx.tk.RenderJob.run() RenderJob.java:58
  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) ThreadPoolExecutor.java:1135
  java.util.concurrent.ThreadPoolExecutor$Worker.run() ThreadPoolExecutor.java:635
  com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run() QuantumRenderer.java:125
  java.lang.Thread.run() Thread.java:844

And one of the application thread:

JavaFX Application Thread  Waiting CPU usage on sample: 0ms
  jdk.internal.misc.Unsafe.park(boolean, long) Unsafe.java (native)
  java.util.concurrent.locks.LockSupport.park(Object) LockSupport.java:194
  java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt() AbstractQueuedSynchronizer.java:883
  java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(int) AbstractQueuedSynchronizer.java:1037
  java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(int) AbstractQueuedSynchronizer.java:1343
  java.util.concurrent.CountDownLatch.await() CountDownLatch.java:232
  com.sun.javafx.tk.quantum.PaintCollector.waitForRenderingToComplete() PaintCollector.java:157
  com.sun.javafx.tk.quantum.GlassScene.waitForRenderingToComplete() GlassScene.java:122
  javafx.scene.Scene$ScenePulseListener.pulse() Scene.java:2528
  com.sun.javafx.tk.Toolkit.lambda$runPulse$2(TKPulseListener) Toolkit.java:410
  com.sun.javafx.tk.Toolkit$$Lambda$941.run()
  java.security.AccessController.doPrivileged(PrivilegedAction, AccessControlContext) AccessController.java (native)
  com.sun.javafx.tk.Toolkit.runPulse(TKPulseListener, AccessControlContext) Toolkit.java:409
  com.sun.javafx.tk.Toolkit.firePulse() Toolkit.java:436
  com.sun.javafx.tk.quantum.QuantumToolkit.pulse(boolean) QuantumToolkit.java:518
  com.sun.javafx.tk.quantum.QuantumToolkit.pulse() QuantumToolkit.java:498
  com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue() QuantumToolkit.java:491
  com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11() QuantumToolkit.java:319
  com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$98.run()
  com.sun.glass.ui.InvokeLaterDispatcher$Future.run() InvokeLaterDispatcher.java:96
  com.sun.glass.ui.win.WinApplication._runLoop(Runnable) WinApplication.java (native)
  com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(int, Runnable) WinApplication.java:175
  com.sun.glass.ui.win.WinApplication$$Lambda$94.run()
  java.lang.Thread.run() Thread.java:844

Here a screenshot from cpu profiling: enter image description here

And the file containing the corresponding data: https://drive.google.com/file/d/1k4t5Q4pgkAvvnnLGx3sph345ccdjYg5W/view?usp=sharing

What could I try to find out more? I wanna know what UI element causes this so I can build a minimal reproducable example.


Solution

  • It seems like the website we load has an animation for loading being:

    <div id="imageLoadingDiv">
      <style>
        .loader {
          width: 100px;
          height: 100px;
        }
    
        .circular{
          animation: rotate 2s linear infinite;
          height: 100px;
          position: relative;
          width: 100px;
        }
    
        .path {
          stroke-dasharray: 1px,200px;
          stroke-dashoffset: 0;
          animation:
              dash 1.5s ease-in-out infinite,
              color 6s ease-in-out infinite
        ;
          stroke-linecap: round;
        }
    
        @keyframes rotate{
          100%{
            transform: rotate(360deg);
          }
        }
        @keyframes dash{
          0%{
            stroke-dasharray: 1px,200px;
            stroke-dashoffset: 0;
          }
          50%{
            stroke-dasharray: 89px,200px;
            stroke-dashoffset: -35;
          }
          100%{
            stroke-dasharray: 89px,200px;
            stroke-dashoffset: -124;
          }
        }
        @keyframes color{
          100%, 0%{
            stroke: #d62d20;
          }
          40%{
            stroke: #0057e7;
          }
          66%{
            stroke: #008744;
          }
          80%, 90%{
            stroke: #ffa700;
          }
        }
      </style>
      <div class="loader">
        <svg class="circular">
          <circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
        </svg>
      </div>
    </div>
    

    Replacing it does seem to remove the issue.