在Java 8更新45中,将这些选项添加到java
调用中:
-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
问题在于“停止线程”的时间很长。在这个例子中,它已经达到了6秒,这对我们的应用程序来说已经是一个问题了,但我曾经看到过更长的时间,比如在某个实例中(虽然没有完整的日志记录),达到了将近一分钟。
VM操作(这里是 no vm operation
)是不稳定的。我也见过其他操作,例如 RevokeBias
、 G1IncCollectionPause
或 GCG_Operation
。另外, page_trap_count
似乎不相关。我见过一些示例,其中它是0,而其他示例中它是2。不过,值得注意的是,这些时间值总是反映在 spin
和 sync
的值中。
我正在寻找对这些时间值 spin
和 sync
的深入解释,但我更感兴趣的是为什么会发生这种情况以及我可以采取什么措施。我不知道我们的配置中是否存在任何“恶意行为”。机器上有大量闲置的核心和未使用的内存,我们正在运行纯Java(没有JNI),并且我们不知道我们的代码中是否存在过度的同步。