在使用G1收集器时,我们一直在努力解决世界暂停的问题。我已经阅读了Oracle文档但我仍然无法确定如何解释导致长时间停顿的原因以及对此有何影响。 (GC日志如下)
我们的实例正在受到监控,我的信息包含在下面的图表中:
我们有另一个监控JVM的监控工具,我报告说JVM在同一时间内没有响应12秒。
这让我想到了如何处理这个问题。服务器上的负载非常低,所以这种情况并不经常发生,但似乎在几个小时内堆只会增长和增长,然后会出现一个巨大的GC事件,可能会导致严重的问题。以下是我们用于GC的配置:
wrapper.java.additional.40=-XX:+UseG1GC
wrapper.java.additional.44=-XX:+ScavengeBeforeFullGC
wrapper.java.additional.50=-XX:+PrintGCCause
wrapper.java.additional.51=-XX:+PrintGCDetails
wrapper.java.additional.52=-XX:+PrintGCTimeStamps
wrapper.java.additional.53=-XX:+PrintGCApplicationStoppedTime
wrapper.java.additional.54=-XX:+PrintGCApplicationConcurrentTime
wrapper.java.additional.55=-verbose:gc
wrapper.java.additional.56=-Xloggc:../../../logs/gc.log
wrapper.java.additional.57-XX:+UseGCLogFileRotation
wrapper.java.additional.58-XX:NumberOfGCLogFiles=10
wrapper.java.additional.59-XX:GCLogFileSize=100M
wrapper.java.additional.60=-XX:+PrintHeapAtGC
wrapper.java.additional.61=-XX:+PrintTenuringDistribution
wrapper.java.additional.62=-XX:+UseCompressedClassPointers
wrapper.java.additional.63=-XX:+UseCompressedOops
任何人都可以在这里指出我正确的方向。谢谢!
GCEasy分析:http://gceasy.io/my-gc-report.jsp?p=c2hhcmVkLzIwMTcvMDYvMjcvLS1nYyAoMSkubG9nLnppcC0tMTgtNDEtNDA=
更新:元空间图
更新:GC日志:https://dl.dropboxusercontent.com/u/3642047/gc.log.zip
答案 0 :(得分:2)
我在GC日志中发现至少两个问题:
System.gc()
或Runtime.getRuntme().gc()
明确调用了4个完整集合。每个都是大约10秒钟:
277042.600: [Full GC (System.gc()) 12G->1537M(5126M), 11.4203806 secs]
您可能希望添加-XX:+ExplicitGCInvokesConcurrent
JVM标记,以防止System.gc()
导致世界各地的事件发生。
找到谁调用System.gc()
并且可能完全避免此调用也很有用。为此,您可以通过添加代码来修改Runtime.gc
方法来打印堆栈跟踪。然后重新编译Runtime.java
并将修改后的类添加到bootstrap类路径中
-Xbootclasspath/p:/path/to/yourpatch.jar
另一个问题是与GC无关的极长安全点同步暂停:
5512447.686: Total time for which application threads were stopped: 16.4426008 seconds, Stopping threads took: 16.4414390 seconds
这通常是由MappedByteBuffer I / O引起的,或者是因为Java进程开始交换到磁盘。有关类似问题,请参阅this和this个答案。