【问题标题】:How to tuning JVM 8 G1 argument to avoid Full GC (Allocation Failure)如何调整 JVM 8 G1 参数以避免 Full GC(分配失败)
【发布时间】:2019-02-01 10:08:42
【问题描述】:

在 XMX 为 8 GB 的服务器中使用 G1 GC 时,运行几天后会发生 Full GC 失败。

尝试多次调整JVM GC参数,打印出所有GC细节但仍然无法确定根本原因

JVM 参数

java -Xms8g -Xmx8g 
-XX:+CrashOnOutOfMemoryError 
-XX:+AlwaysPreTouch 
-XX:-UseBiasedLocking 
-XX:MaxTenuringThreshold=15 
-Xss256k 
-XX:SurvivorRatio=6 
-XX:+UseTLAB 
-XX:GCTimeRatio=4 
-XX:+ScavengeBeforeFullGC 
-XX:G1HeapRegionSize=8M 
-XX:ConcGCThreads=8 
-XX:G1HeapWastePercent=10 
-XX:+AggressiveOpts 
-XX:MaxMetaspaceSize=256m 
-XX:+UseG1GC 
-XX:InitiatingHeapOccupancyPercent=35 
-XX:+DisableExplicitGC 
-Xloggc:/var/tmp/prod/query/Portfolio/PORTFOLIO-QRY-A-Instance1/query-gc.log
-verbose:gc 
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+PrintGCTimeStamps 
-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=10 
-XX:GCLogFileSize=100M 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/var/tmp/prod/query/xxx.log-XX:NewSize=3g 
-XX:MaxNewSize=5g 
-server

最后一次 GC 详情:

2019-01-25T00:25:28.998+0800: 399236.910: [GC 暂停(G1 疏散 暂停)(年轻)(初始标记)(空间耗尽),0.3400461 秒]
[伊甸园:1080.0M(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆: 8144.0M(8192.0M)->7936.0M(8192.0M)] [时间:用户=2.22 系统=0.01,实际=0.34 秒] 2019-01-25T00:25:29.338+0800:399237.251:[GC 并发根区域扫描开始] 2019-01-25T00:25:29.338+0800: 399237.251:[GC 并发根区域扫描结束,0.0000869 秒] 2019-01-25T00:25:29.338+0800:399237.251:[GC 并发标记开始] 2019-01-25T00:25:29.419+0800:399237.332:[GC 暂停(G1 疏散 暂停)(年轻)(空间耗尽),0.2033834 秒] [伊甸园: 208.0M(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.67 sys=0.02, real =0.21 秒] 2019-01-25T00:25:29.624+0800: 399237.537: [GC 暂停 (G1 疏散暂停)(年轻),0.0076649 秒] [伊甸园: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.07 sys=0.00, real =0.01 秒] 2019-01-25T00:25:29.632+0800: 399237.545: [GC 暂停 (G1 疏散暂停)(年轻),0.0072213 秒] [伊甸园: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.06 sys=0.00, real =0.01 秒] 2019-01-25T00:25:29.640+0800: 399237.553: [GC 暂停 (G1 疏散暂停)(年轻),0.0032099 秒] [伊甸园: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.02 sys=0.01, real =0.00 秒] 2019-01-25T00:25:29.645+0800: 399237.557: [GC 暂停 (G1 疏散暂停)(年轻),0.0041076 秒] [伊甸园: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.03 sys=0.00, real =0.00 秒] 2019-01-25T00:25:29.649+0800: 399237.562: [GC 暂停 (G1 疏散暂停)(年轻),0.0027963 秒] [伊甸园: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.01 sys=0.00, real =0.01 秒] 2019-01-25T00:25:29.653+0800: 399237.566: [GC 暂停 (G1 疏散暂停)(年轻),0.0027614 秒] [伊甸园: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->8144.0M(8192.0M)] [时间:user=0.02 sys=0.00, real =0.00 秒] 2019-01-25T00:25:29.656+0800: 399237.569: [完整 GC (分配失败) 8144M->4016M(8192M), 10.6192450 secs] [Eden: 0.0B(3072.0M)->0.0B(3072.0M) 幸存者:0.0B->0.0B 堆:8144.0M(8192.0M)->4016.1M(8192.0M)],[元空间:83995K->83979K(1126400K) ] [时间:用户=15.73 系统=0.00,真实=10.62 秒] 2019-01-25T00:25:40.277+0800:399248.190:[GC concurrent-mark-abort] 堆垃圾优先堆总 8388608K,已使用 4268154K [0x00000005c0000000, 0x00000005c0802000, 0x00000007c0000000) 区域大小 8192K,20 个年轻 (163840K),0 个幸存者 (0K) 元空间
已用 84034K,容量 85146K,已承诺 86732K,预留 1126400K
使用的类空间 8833K,容量 9090K,承诺 9420K,保留 1048576K


我们的服务器是32G 16核,任何意见或建议将不胜感激!

【问题讨论】:

  • "我们的服务器是 32G"-Xmx8g - 看起来答案很明显,不是吗?

标签: java memory memory-leaks garbage-collection jvm


【解决方案1】:

这很复杂。

在日志中发现老年代做full GC太小了。

“分配失败”显示直接分配到老年代失败。

但是,从日志中我也发现full GC之前的minor GC太频繁了,释放了一点空间。在 25:29.338 25:29.653 之间有 7 次 Minor GC。只有第一次 Minor GC 释放了一些空间。

最糟糕的问题是“[Eden: 0.0B(3072.0M)->0.0B(3072.0M) Survivors: 0.0B->0.0B”。似乎所有对象都在老年代分配。从日志“[Eden: 0.0B(3072.0M)->0.0B(3072.0M) Survivors: 0.0B->0.0B Heap: 8144.0M(8192.0M)-> 4016.1M(8192.0M)]",我认为这次full GC释放了4000M+老年代空间。这很奇怪。您的应用程序至少需要 4G 的老年代,并且几乎所有老年代中的对象都被回收。这意味着旧对象还不够老。他们中的大多数过早地被提拔。或者其中大部分是巨大的物体。

我试着给你一些建议......

  1. -XX:InitiatingHeapOccupancyPercent=35 太小了。 使得minor GC更加频繁,对象可能被提前提升。所以老一代很快就会满了。您可以将 XX:InitiatingHeapOccupancyPercent 设置得更大。或者您可以考虑自适应 IHOP。
  2. 老年代太小了。 一些应用程序需要比年轻代空间大得多的老年代空间。有人说双倍或三倍的年轻代空间大小很好。

  3. MaxTenuringThreshold=15可以设置为大于20的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多