在XMX为8GB的服务器中使用G1 GC时,运行几天后会发生完全GC故障。
尝试调整JVM参数,并打印出所有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秒时间: user=2.22 sys=0.01,real=0.34 secs 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秒时报: user=0.67 sys=0.02,real=0.21 secs 2019-01-25T00:25:29.624+0800: 399237.537: GC暂停(G1疏散暂停)(年轻),0.0076649秒时代: user=0.07 sys=0.00,real=0.01 secs 2019-01-25T00:25:29.632+0800: 399237.545: GC暂停(G1疏散暂停)(年轻),0.0072213秒时代: user=0.06 sys=0.00,real=0.01 secs 2019-01-25T00:25:29.640+0800: 399237.553: GC暂停(G1疏散暂停)(年轻),0.0032099秒时报: user=0.02 sys=0.01,real=0.00 secs 2019-01-25T00:25:29.645+0800: 399237.557: GC暂停(G1疏散暂停)(年轻),0.0041076秒时报: user=0.03 sys=0.00,real=0.00 secs 2019-01-25T00:25:29.649+0800: 399237.562: GC暂停(G1后撤暂停)(年轻),0.0027963秒时报: user=0.01 sys=0.00,real=0.01 secs 2019-01-25T00:25:29.653+0800: 399237.566: GC暂停(G1后撤暂停)(年轻),0.0027614秒时报: user=0.02 sys=0.00,real=0.00 secs 2019-01-25T00:25:29.656+0800: 399237.569:完全GC (分配失败) 8144M->4016M(8192M),10.6192450秒,Metaspace: 83995K->83979K(1126400K) 2019-01-25T00:25:40.277+0800: 399248.190: GC并发标记- heap垃圾-第一堆8388608K,使用4268154K [0x00000005c00000 000,0x00000005c0802000,0x00000007c0000000)区域大小8192 K,20年轻(163840K),幸存者(0K) 使用84034K,容量85146 K,承诺86732K,预留1126400 K 类空间使用8833K,容量9090K,提交9420 K,预留1048576K
我们的服务器是32G16核心,如有任何建议或建议将不胜感激!
发布于 2019-02-02 14:12:37
很复杂哦。
在日志中,我发现由于老一代的原因,执行完整的GC太小了。
“分配失败”表明,直接分配给老一代失败了。
但是,从日志中我还发现,在完全GC之前的小GC太频繁,并且有一点空间。在25:29.338,25:29.653之间有7个小GC。只有第一个小GC释放了一些空间。
最糟糕的问题是“[Eden: 0.0B(3072.0M)->0.0B(3072.0M)幸存者:0.0B->0.0B”。所有对象似乎都是在旧generation.From中分配的日志"Eden: 0.0B(3072.0M)->0.0B(3072.0M)幸存者:0.0B->0.0BHeap: 8144.0M(8192.0M)->4016.1M(8192.0M)",我认为这个完整的GC释放了4000M+老代空间。太奇怪了。您的应用程序需要至少4G老一代和几乎所有的对象在老一代被回收。这意味着旧的对象还不够老。他们中的大多数都提前升迁了。或者大部分是巨大的物体。
我试着给你一些建议。
- [understanding g1 gc log](https://blog.gceasy.io/2016/07/07/understanding-g1-gc-log-format/)
- [G1 Collector](https://docs.oracle.com/en/java/javase/11/gctuning/garbage-first-garbage-collector.html#GUID-AC383806-7FA7-4698-8B92-4FD092B9F368)
https://stackoverflow.com/questions/54477197
复制相似问题