我正在测试基于Jetty的API与基于Netty的API。实验中唯一不同的是我使用的API(相同的应用程序,相同的服务器,相同的内存配置,相同的负载等),我使用基于Netty的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
停止了世界?
答案 0 :(得分:3)
并非所有STW暂停 - 用于触发它们的机制称为safepoint - 由GC引起,使用-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1
打印其他安全点原因。
其次,如果暂停是由GC引起的,那么您粘贴的行本身不包含原因,但GC日志中的相邻块应包含原因,如{{1} }
此外,您可能还希望监视磁盘IO延迟并将时间戳与安全停顿相匹配。在安全点期间发生的任何同步IO或分页进入慢速存储可能会使整个安全点停顿。将日志文件和[GC pause (G1 Evacuation Pause) (young), 0.0200285 secs]
放在tmpfs或SSD上可能有帮助。
答案 1 :(得分:1)
为此添加一些闭包:问题是,从技术上讲,这不是GC停顿;它是几个因素的组合:
我们的应用程序的其他部分达到了EBS限制阈值,当JVM在STW期间尝试写入/ tmp时,JVM上的所有线程都排在AWS限制点后面。
似乎Netty / Jetty的区别是红鲱鱼。
我们需要我们的应用程序在这种环境中生存,所以我们的解决方案是禁用这种JVM行为,代价是失去了我们添加的几个JVM工具的支持:
-XX:+PerfDisableSharedMem
此优秀博文中有关此问题的更多信息:http://www.evanjones.ca/jvm-mmap-pause.html