在 Java 8 Update 45 中,将这些选项添加到java
call:
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
显示如下统计数据:
vmop [threads: total initially_running wait_to_block] [time: spin block sync cleanup vmop] page_trap_count
3679.229: no vm operation [ 72 1 2 ] [ 6016 0 6016 0 0 ] 1
2015-05-22T11:25:27.519+0200: Total time for which application threads were stopped: 6.0168551 seconds, Stopping threads took: 6.0164099 seconds
这里的问题是时间很长Stopping threads
。在这个例子中,它是 6 秒,这对于我们的应用程序来说已经是一个问题,但我见过更长的时间,在一个实例中(尽管没有完整的日志记录)几乎达到一分钟。
虚拟机操作(此处:no vm operation
) 是变化的。我也见过,例如RevokeBias
, G1IncCollectionPause
, or GCG_Operation
。另外,page_trap_count
似乎无关紧要。我见过它为 0 的例子,也见过它为 2 的例子。不过,一致的是,时间总是反映在spin
and sync
.
我正在寻找这些计时值的深入解释spin
and sync
,但我最感兴趣的是为什么会发生这种情况以及我可以采取什么措施来应对它。我不知道我们的配置中有任何“邪恶”的东西。机器上有大量无聊的核心和未使用的内存,我们正在运行纯 Java(无 JNI),并且我们没有意识到代码中存在任何过度同步。
这里的问题是您的应用程序需要很长时间才能达到安全点。这Stopping threads
输出表示 JVM 发出安全点请求到所有线程到达安全点之间所花费的时间。
The sync
value 显示了同样的事情 - 这是所有线程到达 safeponit 所需的时间。
The spin
and block
值表示所需的时间blocked
and spinning
(执行代码)线程到达安全点。
了解这一点后,我们可以得出结论,您面临的问题是一个线程正忙于旋转,并且无法在几秒钟内到达其安全点。
究竟为什么会发生这种情况很难说。一个例子,如图所示this https://stackoverflow.com/questions/20134769/how-to-get-java-stacks-when-jvm-cant-reach-a-safepoint问题的答案是 JIT 编译器可以编译繁重的循环而无需安全点检查。
您可以尝试使用以下选项运行 JVM-XX:+SafepointTimeout -XX:SafepointTimeoutDelay=500
。这将使安全点同步在 500 毫秒后超时,并打印有关未能到达安全点的线程的信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)