JavaFX 8 QuantumRenderer CPU使用率很高

Luc*_*ian 19 cpu javafx renderer

我有一个JavaFX APP,其中包含两个列表视图,显示从我的服务器收到的传入客户订单(使用自定义cellfactory).我还有一些tableview显示来自Postgres数据库的信息(这些信息分布在tabpane中的几个选项卡中).用户必须接受订单(通过点击它),并在文本框中输入一些信息.

该应用程序最初是使用Java7编写的.我没有任何问题.但最近我决定改用Java8.我修改了我的代码以使用lambdas并在应用程序中添加了一些额外的东西:

  • 在文本流中每分钟检查和显示订单状态的时间表;
  • 修改了customcellfactory类以使用外部CSS,使用setId而不是setStyle;
  • ...

现在,应用程序运行良好,但在运行2-3小时后,它变得迟缓.因为对我来说我模拟使用jstack分析器内的行为,是硬top -H,并匹配pidnid找出发生了什么.

这样我发现罪魁祸首是QuantumRendererCPU使用率为95 +%:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
30300 utilizat+  20   0 5801608 527412  39696 S  95,1  6,5  60:57.34 java

"QuantumRenderer-0" #9 daemon prio=5 os_prio=0 tid=0x00007f4f182bb800 nid=0x765c runnable [0x00007f4eeb2a1000]
   java.lang.Thread.State: RUNNABLE
    at com.sun.prism.es2.X11GLDrawable.nSwapBuffers(Native Method)
    at com.sun.prism.es2.X11GLDrawable.swapBuffers(X11GLDrawable.java:50)
    at com.sun.prism.es2.ES2SwapChain.present(ES2SwapChain.java:186)
    at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:107)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

运行应用程序的机器使用的是润滑剂的64位版本.

我无法弄清楚我应该在哪里找出问题所在......

Jav*_*erJ 5

您的渲染器似乎正在使用 X11 管道(Java2D?),这可能是 CPU 使用率高(软件加速)的原因。你的显卡支持硬件加速吗?

尝试获取更多信息,-Dprism.verbose=true如果您的显卡确实支持硬件加速,您可能想尝试强制使用-Dprism.forceGPU=true,还尝试启用 OpenGL 管道以提高 Java2D 性能 -Dprism.order=es2,es1,sw,j2d(您也可以尝试使用旧的 Java2D 标志, -Dsun.java2d.opengl=true但我认为这不会' t 影响棱镜)。

我还建议您查看 OpenJFX性能提示和技巧清单,我发现节点中的 CPU 使用率很高,使用任何类型的动画(使用缺点是这会使用更多内存)。

另外,看看如何从工作线程更新 UI。在 FX UI 线程中做最少的工作并正确地从工作人员更新它非常重要,并且仅在必要时,请查看另一个问题以了解有关javafx.concurrent.Task类及其更新 UI 的正确用法的更多信息工作线程。

这看起来更像是一个软件加速问题,Dprism.verbose 应该让您了解更多信息,但遵循其他建议永远不会有坏处!希望这可以帮助!

  • 很高兴您解决了您的问题!我不确定我可能会“出错”,因为我建议了很多事情,其中​​包括使用 prism.order 在渲染顺序中添加软件加速。如果您通过其他标志或操作解决了此问题,请添加您的答案,以便每个人都可以从准确的响应中受益。 (2认同)