2

我正在测试基于 Jetty 的 API 与基于 Netty 的 API。实验中唯一的区别是我使用的 API(相同的应用程序、相同的服务器、相同的内存配置、相同的负载等),我使用基于 Netty 的 API 获得了更长的 GC 暂停。大多数情况下,停顿低于一毫秒,但在平稳运行几天后,每 12-24 小时我会看到 4-6 秒的停顿,而基于 Jetty 的 API 不会出现这种停顿。

每当发生这种情况时,关于 G1 正在做什么导致它发出 STW 的信息非常少,请注意此处的第二条暂停消息:

2016-02-23T05:22:27.709+0000: 66360.282: Total time for which application threads were stopped: 0.0319639 seconds, Stopping threads took: 0.0000716 seconds
2016-02-23T05:22:35.642+0000: 66368.215: Total time for which application threads were stopped: 6.9705594 seconds, Stopping threads took: 0.0000737 seconds
2016-02-23T05:22:35.673+0000: 66368.246: Total time for which application threads were stopped: 0.0048374 seconds, Stopping threads took: 0.0040574 seconds 

我的 GC 选项是:

-XX:+UseG1GC 
-XX:+G1SummarizeConcMark 
-XX:+G1SummarizeRSetStats 
-XX:+PrintAdaptiveSizePolicy 
-XX:+PrintGC 
-XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCDateStamps 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+DisableExplicitGC 
-XX:InitialHeapSize=12884901888 
-XX:MaxHeapSize=12884901888 

而且,作为参考,我的 VM 选项是:

-XX:+AlwaysPreTouch 
-XX:+DebugNonSafepoints 
-XX:+FlightRecorder 
-XX:FlightRecorderOptions=stackdepth=500 
-XX:-OmitStackTraceInFastThrow 
-XX:+TrustFinalNonStaticFields 
-XX:+UnlockCommercialFeatures 
-XX:+UnlockDiagnosticVMOptions 
-XX:+UnlockExperimentalVMOptions 
-XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops 

我如何找出为什么G1 停止了世界2016-02-23T05:22:35.642

4

2 回答 2

3

并非所有 STW 暂停(用于触发它们的机制称为安全点)都是由 GC 引起的,用于-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1打印其他安全点原因。

其次,如果暂停是由 GC 引起的,那么您粘贴的行本身不包含原因,但 GC 日志中的相邻块应该包含原因,例如[GC pause (G1 Evacuation Pause) (young), 0.0200285 secs]

此外,您可能还想监控磁盘 IO 延迟并将时间戳与安全点暂停相匹配。在安全点期间发生的任何同步 IO 或分页都会导致存储速度变慢,这可能会使整个安全点停滞。将日志文件/tmp放在 tmpfs 或 SSD 上可能会有所帮助。

于 2016-02-25T05:29:21.397 回答
1

对此添加一些关闭:问题在于,从技术上讲,这不是 GC 暂停;这是几个因素的结合:

  • AWS 将 IO 限制为您支付的费用
  • 默认情况下,Ubuntu 上的 /tmp 在我们的(受限制的)EBS 卷上结束
  • 默认情况下,JVM 在 stop-the-world(!) 期间写入 /tmp

我们应用程序的其他部分达到了 EBS 限制阈值,当 JVM 在 STW 期间尝试写入 /tmp 时,JVM 上的所有线程都在 AWS 限制点后面排队。

似乎 Netty/Jetty 的区别是一条红鲱鱼。

我们需要我们的应用程序在这种环境中生存,所以我们的解决方案是禁用这种 JVM 行为,代价是失去了我们添加的几个 JVM 工具的支持:

-XX:+PerfDisableSharedMem

这篇优秀的博客文章中关于这个问题的更多信息:http ://www.evanjones.ca/jvm-mmap-pause.html

于 2017-04-10T18:00:28.507 回答