是否有我可以尝试调试在关闭时挂起的 JavaFX 进程的高级故障排除技术?

Are there advanced troubleshooting techniques I can try to debug a JavaFX process that hangs on close?

所以这个有点像面条刮擦器,我想知道是否有人对我可能能够深入了解的事情有想法。

JRE/JDK is 1.8.0_251, 运行ning on Windows 10.应用程序是使用launch4j启动的JavaFX应用程序。

有时当我退出应用程序时,JVM 不会关闭。相反,我有一个进程卡在任务管理器中,直到我明确关闭它。以前是间歇性的,现在几乎是恒定的。

我怀疑我有一个用户线程卡住了,它阻止了应用程序的关闭。但是,我无法收集有用的线程转储来查看是否可以确定线程的创建位置。

当我 运行 遇到这种情况时,我通过 tasklist / wmic 识别进程 ID(JMC 没有看到该进程),然后我尝试 运行 jstack 反对它:

如果我能获得 运行 jstack -l 返回的能力,这将大大有助于我识别导致此问题的执行程序池。该应用程序产生了几个不同的池,我所知道的几个都明确地在它们生成的线程上设置了守护进程标志。

有趣的是,当从 Eclipse 运行连接应用程序时,我遇到了类似的问题。 None 我团队中的其他人可以重现此问题,而此问题仅在我收到替换笔记本电脑后才出现。你会认为如果有一个粘性用户线程,其他人会看到同样的问题。这让我觉得可能 environmental/hardware 涉及某些东西,或者我可能触发了 JRE 错误。

有没有人成功解决过像这样的 jstack 挂起的问题?当应用程序无法关闭时获取线程转储的任何技巧?

所以,在再次研究这个问题一段时间后,我至少取得了一些进展,并且对导致问题的原因有了一个很好的了解,尽管还不一定如何解决它。

通过 jstack -F 获取的线程转储包含一个我错过的线索行,因为我关注的是接收到的输出中没有线程名称/守护进程状态:

Thread 22: (state = IN_NATIVE)
- com.sun.prism.d3d.D3DPipeline.nDispose() u/bci=0 (Interpreted frame)
- com.sun.prism.d3d.D3DPipeline.dispose() u/bci=49, line=164 (Interpreted frame)
- com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.cleanup() u/bci=9, line=118 (Interpreted frame)
- com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run() u/bci=14, line=127 (Interpreted frame)
- java.lang.Thread.run() u/bci=11 (Interpreted frame)

做了 Java 多年的支持,我知道硬件加速 Java UI 可能会遇到某些显卡/驱动程序的问题。所以我尝试使用 JVM 上的 -Dsun.java2d.d3d=false 标志禁用 d3d 渲染器。无法重现挂起。

当然,仅禁用硬件加速对我来说并不是理想的解决方案,因此我一直在深入研究以解决该问题。上面的调用堆栈使我了解了 -Dprism.verbose 标志,它为我提供了有关正在使用的卡的更多信息。 (内部 Intel GPU 而不是我的外部 GPU)

我已经尝试升级驱动程序,并将研究如何将 Prism 从使用英特尔芯片组切换到我的专用 GPU,看看是否能解决问题。但至少,我确实可以选择完全禁用 d3d 加速。