JavaFX 8 QuantumRenderer CPU使用率高

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (389)

我有一个JavaFX APP,其中包含两个列表视图,显示从我的服务器收到的传入客户订单(使用自定义cellfactory)。我也有几个tableview显示来自Postgres数据库的信息(这些信息分布在Tabpane中的几个标签上)。用户必须下单(点击它),然后在文本框内输入一些信息。

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

  • 在文本流内每分钟检查并显示订单状态的时间表;
  • 修改customcellfactory类以使用外部CSS,setId代替setStyle;
  • ...

现在,该应用程序运行良好,但在正常运行时间2-3小时后,它变得缓慢。由于我很难模拟探查器内部的行为,所以我使用jstack top -H,并pid与之匹配nid以找出发生的事情。

这样我发现罪魁祸首是QuantumRenderer95%以上的CPU使用率:

  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)

运行该应用程序的机器使用的是Lubuntu的64位版本。

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

提问于
用户回答回答于

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

尝试获得更多信息,与-Dprism.verbose=true如果你的显卡不支持硬件加速,你可能想尝试迫使它-Dprism.forceGPU=true,也尽量使OpenGL的管道,以增加的Java2D性能 -Dprism.order=es2,es1,sw,j2d(你也可以尝试与旧Java2D的标志 -Dsun.java2d.opengl=true,但我认为,韩元”不影响棱镜)。

我还建议看看OpenJFX的性能提示和技巧清单我已经看到在使用任何类型的动画时使用Node.setCache(true)和其CacheHints在某种程度上解决了较高的CPU使用率问题(使用缺点是这使用更多的内存)。

另外,看看你如何从工作线程更新你的UI。在FX UI Thread中进行最低限度的工作并且正确地从工作人员更新它是很重要的,并且只有在必要时,才能看到另一个问题,以了解更多关于javafx.concurrent.Task类及其更正UI的正确用法工作者线程。

这似乎更像是一个软件加速问题,Dprism.verbose应该让你知道更多,但遵循其他建议永远不会伤害!

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动