如何调整JVM 8 G1参数以避免完全GC(分配失败)

时间:2019-02-01 10:08:42

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

在XMX为8 GB的服务器中使用G1 GC时,运行几天后会发生完全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 sys = 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秒] [Eden:   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,真实= 0.21秒] 2019-01-25T00:25:29.624 + 0800:399237.537:[GC暂停   (G1疏散暂停)(年轻),0.0076649秒] [Eden:   0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B堆:8144.0M(8192.0M)-> 8144.0M(8192.0M)] [时间:用户= 0.07 sys = 0.00,真实= 0.01秒] 2019-01-25T00:25:29.632 + 0800:399237.545:[GC暂停   (G1疏散暂停)(年轻),0.0072213秒] [Eden:   0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B堆:8144.0M(8192.0M)-> 8144.0M(8192.0M)] [时间:用户= 0.06 sys = 0.00,真实= 0.01秒] 2019-01-25T00:25:29.640 + 0800:399237.553:[GC暂停   (G1撤离暂停)(年轻),0.0032099秒] [Eden:   0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B堆:8144.0M(8192.0M)-> 8144.0M(8192.0M)] [时间:用户= 0.02 sys = 0.01,实际= 0.00秒] 2019-01-25T00:25:29.645 + 0800:399237.557:[GC暂停   (G1疏散暂停)(年轻),0.0041076秒] [Eden:   0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B堆:8144.0M(8192.0M)-> 8144.0M(8192.0M)] [时间:用户= 0.03 sys = 0.00,真实= 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)] [时间:用户= 0.01 sys = 0.00,真实= 0.01秒] 2019-01-25T00:25:29.653 + 0800:399237.566:[GC暂停   (G1疏散暂停)(年轻),0.0027614秒] [Eden:   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,真实= 0.00秒] 2019-01-25T00:25:29.656 + 0800:399237.569:[完整GC   (分配失败)8144M-> 4016M(8192M),10.6192450秒] [Eden:   0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B堆:8144.0M(8192.0M)-> 4016.1M(8192.0M)],[Metaspace:83995K-> 83979K(1126400K) ] [时间:user = 15.73 sys = 0.00,真实= 10.62   secs] 2019-01-25T00:25:40.277 + 0800:399248.190:[GC   parallel-mark-abort]堆垃圾优先堆总计8388608K,已使用   4268154K [0x00000005c0000000、0x00000005c0802000、0x00000007c0000000)   地区大小8192K,20个年轻(163840K),0个幸存者(0K)元空间
  二手84034K,容量85146K,已承诺86732K,预留1126400K
  类空间使用了8833K,容量9090K,已提交9420K,保留   1048576K


我们的服务器是32G 16核,我们将不胜感激!

1 个答案:

答案 0 :(得分:0)

这很复杂。

在日志中,我发现由于老一代而进行完整的GC太小了。

“分配失败”表明直接分配给上一代失败。

但是,从日志中,我还发现,完整GC之前的次要GC太频繁了,并且释放了一些空间。 25:29.338 25:29.653之间有7个次要GC。只有第一个次要GC释放了一些空间。

最严重的问题是“ [伊甸园:0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B”。似乎所有对象都是旧的对象。从日志“ [Eden:0.0B(3072.0M)-> 0.0B(3072.0M)幸存者:0.0B-> 0.0B堆:8144.0M(8192.0M)-> 4016.1M(8192.0M)]“,我认为此完整的GC释放了4000M +的旧一代空间。很奇怪您的应用程序至少需要4G的旧版本,并且几乎回收了所有旧版本的对象。这意味着旧对象还不够旧。他们中的大多数人都过早晋升。或其中很多是巨大的物体。

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

  1. -XX:InitiatingHeapOccupancyPercent = 35太小了。这会使次要GC更加频繁,并且对象可能会过早升级。因此,老一辈将很快吃饱。您可以将XX:InitiatingHeapOccupancyPercent设置得更大。或者您可以考虑自适应IHOP。
  2. 老一代太小了。某些应用程序需要比老一代空间更多的老一代空间。有人说两倍或三倍的年轻一代空间大小是好的。

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