如何解释Java G1 GC暂停时间原因

时间:2017-06-27 18:06:13

标签: java garbage-collection jvm g1gc

在使用G1收集器时,我们一直在努力解决世界暂停的问题。我已经阅读了Oracle文档但我仍然无法确定如何解释导致长时间停顿的原因以及对此有何影响。 (GC日志如下)

我们的实例正在受到监控,我的信息包含在下面的图表中:

12 second stop the world pause Heap allocations

我们有另一个监控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=

更新:元空间图

enter image description here

更新:GC日志:https://dl.dropboxusercontent.com/u/3642047/gc.log.zip

1 个答案:

答案 0 :(得分:2)

我在GC日志中发现至少两个问题:

  1. 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

  2. 另一个问题是与GC无关的极长安全点同步暂停:

    5512447.686: Total time for which application threads were stopped: 16.4426008 seconds, Stopping threads took: 16.4414390 seconds
    

    这通常是由MappedByteBuffer I / O引起的,或者是因为Java进程开始交换到磁盘。有关类似问题,请参阅thisthis个答案。