是否有我可以尝试调试在关闭时挂起的 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 -F" 有效,但删除了所有有用的信息,如线程名称或线程类型(守护进程/用户)。 None 个线程包含对我的代码的任何引用。
- "jstack -l" 曾经工作,我看到两个受影响的名为 "pool-#-thread-#" 的线程不是守护线程,但在推送 JRE 更新后我不得不安装 _251 JDK到我的机器,从那时起,它就永远挂起。 (我已经把它留给 运行 几个小时了,没有变化)
如果我能获得 运行 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 加速。
所以这个有点像面条刮擦器,我想知道是否有人对我可能能够深入了解的事情有想法。
JRE/JDK is 1.8.0_251, 运行ning on Windows 10.应用程序是使用launch4j启动的JavaFX应用程序。
有时当我退出应用程序时,JVM 不会关闭。相反,我有一个进程卡在任务管理器中,直到我明确关闭它。以前是间歇性的,现在几乎是恒定的。
我怀疑我有一个用户线程卡住了,它阻止了应用程序的关闭。但是,我无法收集有用的线程转储来查看是否可以确定线程的创建位置。
当我 运行 遇到这种情况时,我通过 tasklist / wmic 识别进程 ID(JMC 没有看到该进程),然后我尝试 运行 jstack 反对它:
- "jstack -F" 有效,但删除了所有有用的信息,如线程名称或线程类型(守护进程/用户)。 None 个线程包含对我的代码的任何引用。
- "jstack -l" 曾经工作,我看到两个受影响的名为 "pool-#-thread-#" 的线程不是守护线程,但在推送 JRE 更新后我不得不安装 _251 JDK到我的机器,从那时起,它就永远挂起。 (我已经把它留给 运行 几个小时了,没有变化)
如果我能获得 运行 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 加速。