如何解释JavaG1GC暂停时间原因

如何解释JavaG1GC暂停时间原因,java,garbage-collection,jvm,g1gc,Java,Garbage Collection,Jvm,G1gc,在使用G1采集器时,我们一直在努力解决“世界暂停”的问题。我已经阅读了Oracle文档,但仍然无法确定如何解释导致长时间暂停的原因以及如何处理它。(下面是GC日志) 我们的实例正在被监视,我的信息包含在以下图表中: 我们有另一个监视工具ping JVM,我让它报告JVM在大约同一时间有12秒没有响应 这就引出了我该怎么办的问题。服务器上的负载非常低,所以这种情况并不经常发生,但似乎在几个小时内堆会不断增长,然后出现一个巨大的GC事件,可能会导致严重的问题。下面是我们用于GC的配置: w

在使用G1采集器时,我们一直在努力解决“世界暂停”的问题。我已经阅读了Oracle文档,但仍然无法确定如何解释导致长时间暂停的原因以及如何处理它。(下面是GC日志)

我们的实例正在被监视,我的信息包含在以下图表中:

我们有另一个监视工具ping 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分析:

更新:元空间图


更新:GC日志:

我发现您的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
    ,并使用
    -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进程开始交换到磁盘。有关类似问题,请参阅和回答


  • 我通过gceasy运行日志,以获得更详细的信息,但这并没有让我更清楚。看来,也许我的年轻一代还不够成熟?您正在使用哪个JVM?我没有看到元空间的任何设置,所以我担心您没有使用JDK8。你应该是。有很多方法可以调整JVM。谢谢。我们使用的是java 8:1.8.0_121。我在原始帖子中添加了元空间信息。既然你有日志,为什么不发布日志,而不是减少信息内容的图形呢?非常棒的观察结果,System.gc应该很容易修复,如果我们能够跟踪libs的调用,我们也使用了一个库,它可以处理大量内存映射文件,有时高达70克或更多。除了在RAM中强制执行之外,还有什么建议可以让操作系统更好地处理这些问题?谢谢@CaseyJordan不幸的是,除了确保文件在RAM中,或者用常规的FileChannel I/O替换映射的I/O,或者禁用JVM中的不安全内部函数(后者可能会显著降低吞吐量),您对此无能为力。