Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是什么导致Java中的旋转和同步时间过长?_Java_Garbage Collection_G1gc - Fatal编程技术网

是什么导致Java中的旋转和同步时间过长?

是什么导致Java中的旋转和同步时间过长?,java,garbage-collection,g1gc,Java,Garbage Collection,G1gc,在Java 8 Update 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_

在Java 8 Update 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操作(此处:
无VM操作
)是可变的。我还见过,例如,
RevokeBias
g1incollectionpause
,或
GCG\u操作
。而且,
页面陷阱计数似乎与此无关。我看到过一些例子,其中0为,其他例子中为2。但一致的是,时间总是反映在
spin
sync
的值中


我正在寻找对这些计时值的深入解释
spin
sync
,但我最感兴趣的是为什么会发生这种情况,以及我可以如何应对它。我不知道我们的配置中有什么“邪恶”。机器上有大量无聊的内核和未使用的内存,我们运行的是纯Java(没有JNI),我们不知道代码中有任何过度同步。

这里的问题是,应用程序需要很长时间才能达到安全点。
停止线程
输出表示JVM发出安全点请求直到所有线程都达到安全点所需的时间

sync
值显示了相同的内容—它是所有线程到达safeponit所需的时间

旋转
阻塞
值表示
阻塞
旋转
(执行代码)线程到达安全点所需的时间

知道了这一点,我们可以得出结论,您的问题是一个线程正在忙于旋转,无法在几秒钟内达到其安全点

确切的原因很难说。一个例子,如问题及其答案所示,JIT编译器可以编译重循环而无需安全点检查


您可以尝试使用选项运行JVM
-XX:+SafepointTimeout-XX:SafepointTimeoutDelay=500
。这将使safepoint同步在500毫秒后超时,并打印有关未能到达safepoint的线程的信息。

您可以提供特定用例的更多详细信息,以便人们知道如何提供帮助。事实上,我不仅在我们的一个应用程序中看到了这一点,而且在所有应用程序中都看到了这一点。因此,实际上没有一个特定的用例。如果我知道该寻找什么,我可以去寻找相似之处。然而,我有点怀疑,很多人都有同样的问题,但还没有注意到。日志'停止线程采取:'这表明我对它是相当新的。谢谢!我将尝试这个并报告回来。额外的选项确实会给我线程名称(没有堆栈,但目前似乎没有办法获得它)。看看出现问题的一个应用程序,大多数情况下线程都是相同的。看起来要找到实际问题需要做一些艰苦的工作,但我现在知道从哪里开始了,这个问题肯定得到了回答@malamut既然您已经了解了线程,那么常规的线程转储(
jstack
)可能会有所帮助。他们也在等待一个安全点,所以即使有这样的帮助,也很难说出问题所在。一旦你确定了问题所在,我很想知道问题出在哪里。这是一个有趣的问题。我将报告有趣的发现。可悲的是,这并不容易,因为这可能不止一个原因。我目前正在寻找的是特定于单个应用程序的。当禁用JIT时,它就消失了,所以我将首先跟踪您链接问题中的轨迹。我确定了我们自己的一个方法,当从编译中排除时,它将解决问题。我真的不相信方法本身就是问题所在;把它排除在外,也许反而隐藏了实际问题。无论如何,我可以把它排除在外,所以现在我就这样做,不再问更多的问题下一步是消除G1暂停时异常长的复制时间。不过,这个问题还没有准备好回答。首先需要进行一些额外的研究。:)