[英]G1 young GC does not free memory - to-space exhausted
I'm using G1GC, jdk 1.7我正在使用 G1GC,jdk 1.7
Java HotSpot(TM) 64-Bit Server VM (24.79-b02) for linux-amd64 JRE (1.7.0_79-b15), built on Apr 10 2015 11:34:48 by "java_re" with gcc 4.3.0 20080428 (Red Hat 4.3.0-8)
Memory: 4k page, physical 32826020k(12590436k free), swap 33431548k(33358800k free)
CommandLine flags: -XX:AutoBoxCacheMax=3000000 -XX:+DisableExplicitGC
-XX:G1NewSizePercent=20 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=10737418240
-XX:InitiatingHeapOccupancyPercent=70 -XX:MaxDirectMemorySize=1073741824 -XX:MaxGCPauseMillis=1000
-XX:MaxHeapSize=10737418240
-XX:-OmitStackTraceInFastThrow -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDetails
-XX:+PrintGCTimeStamps -XX:+UnlockExperimentalVMOptions
-XX:+UseCompressedOops -XX:+UseG1GC
Mostly minor GC works fine, but it still start unusual fullGC, about one to two times in an hour.大多数次要 GC 工作正常,但它仍然会启动不寻常的 fullGC,大约在一小时内发生一到两次。
This is a normal case young GC log这是一个正常情况的年轻GC日志
3443.100: [GC pause (young), 0.3021260 secs]
[Parallel Time: 277.6 ms, GC Workers: 4]
[GC Worker Start (ms): Min: 3443100.5, Avg: 3443100.6, Max: 3443100.6, Diff: 0.1]
[Ext Root Scanning (ms): Min: 2.9, Avg: 3.0, Max: 3.1, Diff: 0.2, Sum: 11.9]
[Update RS (ms): Min: 33.5, Avg: 33.6, Max: 33.9, Diff: 0.4, Sum: 134.5]
[Processed Buffers: Min: 180, Avg: 204.8, Max: 227, Diff: 47, Sum: 819]
[Scan RS (ms): Min: 76.0, Avg: 76.2, Max: 76.3, Diff: 0.3, Sum: 304.9]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.3]
[Object Copy (ms): Min: 164.4, Avg: 164.4, Max: 164.5, Diff: 0.1, Sum: 657.7]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.0, Sum: 0.2]
[GC Worker Total (ms): Min: 277.3, Avg: 277.4, Max: 277.4, Diff: 0.1, Sum: 1109.5]
[GC Worker End (ms): Min: 3443377.9, Avg: 3443378.0, Max: 3443378.0, Diff: 0.0]
[Code Root Fixup: 0.2 ms]
[Code Root Migration: 0.3 ms]
[Clear CT: 2.0 ms]
[Other: 22.1 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 15.7 ms]
[Ref Enq: 0.5 ms]
[Free CSet: 3.2 ms]
[Eden: 5996.0M(5996.0M)->0.0B(5648.0M) Survivors: 148.0M->196.0M Heap: 8934.5M(10.0G)->2997.2M(10.0G)]
[Times: user=1.13 sys=0.00, real=0.30 secs]
And this is a unusual GC log before the fullGC.这是fullGC之前的一个不寻常的GC日志。 It repeated two to three times, and it didn't clean any memory.
它重复了两到三遍,并没有清除任何记忆。
3482.422: [GC pause (young) (to-space exhausted), 3.4878580 secs]
[Parallel Time: 1640.5 ms, GC Workers: 4]
[GC Worker Start (ms): Min: 3482421.8, Avg: 3482422.4, Max: 3482424.0, Diff: 2.2]
[Ext Root Scanning (ms): Min: 2.1, Avg: 3.2, Max: 3.8, Diff: 1.7, Sum: 12.6]
[Update RS (ms): Min: 104.8, Avg: 105.2, Max: 105.6, Diff: 0.8, Sum: 421.0]
[Processed Buffers: Min: 201, Avg: 221.2, Max: 236, Diff: 35, Sum: 885]
[Scan RS (ms): Min: 75.1, Avg: 75.2, Max: 75.3, Diff: 0.1, Sum: 300.8]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.2]
[Object Copy (ms): Min: 1455.9, Avg: 1456.1, Max: 1456.2, Diff: 0.3, Sum: 5824.2]
[Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 0.4]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
[GC Worker Total (ms): Min: 1638.2, Avg: 1639.8, Max: 1640.4, Diff: 2.2, Sum: 6559.3]
[GC Worker End (ms): Min: 3484062.2, Avg: 3484062.2, Max: 3484062.2, Diff: 0.0]
[Code Root Fixup: 0.2 ms]
[Code Root Migration: 0.5 ms]
[Clear CT: 2.0 ms]
[Other: 1844.7 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 60.1 ms]
[Ref Enq: 0.5 ms]
[Free CSet: 1.2 ms]
[Eden: 5648.0M(5648.0M)->0.0B(1876.0M) Survivors: 196.0M->172.0M Heap: 9441.9M(10.0G)->9352.3M(10.0G)]
[Times: user=9.29 sys=0.05, real=3.49 secs]
Then it started a fullGC然后开始了fullGC
3490.812: [Full GC 9626M->1879M(10G), 7.6059670 secs]
[Eden: 0.0B(2048.0M)->0.0B(6144.0M) Survivors: 0.0B->0.0B Heap: 9626.3M(10.0G)->1879.5M(10.0G)], [Perm: 33901K->33901K(36864K)]
[Times: user=10.24 sys=0.00, real=7.61 secs]
Why the last youngGC didn't clean any memory?为什么上次的youngGC没有清理任何内存?
You are suffering from evacuation failures as can be seen by the to-space exhausted
part of the start message for the collection.您正在遭受疏散失败,这可以从集合的开始消息的
to-space exhausted
部分看出。
This occurs when there is not enough free space on your heap to promote survived or promoted objects (or both) and the heap can not be expanded more.当您的堆上没有足够的可用空间来提升存活或提升的对象(或两者)并且堆无法进一步扩展时,就会发生这种情况。
Monica Beckwith writes the following in Tips for Tuning the Garbage First Garbage Collector Monica Beckwith 在调整垃圾优先垃圾收集器的技巧中写了以下内容
For G1 GC, an evacuation failure is very expensive -
对于 G1 GC,疏散失败是非常昂贵的——
- For successfully copied objects, G1 needs to update the references and the regions have to be tenured.
对于成功复制的对象,G1 需要更新引用并且必须对区域进行永久保留。
- For unsuccessfully copied objects, G1 will self-forward them and tenure the regions in place.
对于未成功复制的对象,G1 将自行转发它们并将这些区域保留到位。
Often G1 can't keep up with the allocation rate when forced to do these operations and will eventually be forced to a full GC due to allocation failure.通常,G1 在被迫执行这些操作时无法跟上分配速率,最终会因分配失败而被迫进行 full GC。 This is probably why you see a full GC after a couple of evacuation failures.
这可能就是您在几次疏散失败后看到完整 GC 的原因。
Monica also writes about possible solutions in Garbage First Garbage Collector Tuning Monica 还在Garbage First Garbage Collector Tuning 中撰写了有关可能的解决方案的文章
Increase the value of the -XX:G1ReservePercent option (and the total heap accordingly) to increase the amount of reserve memory for "to-space".
增加 -XX:G1ReservePercent 选项的值(以及相应的总堆)以增加“to-space”的保留内存量。
Start the marking cycle earlier by reducing the -XX:InitiatingHeapOccupancyPercent.
通过减少 -XX:InitiatingHeapOccupancyPercent 来提前开始标记周期。
You can also increase the value of the -XX:ConcGCThreads option to increase the number of parallel marking threads.
您还可以增加 -XX:ConcGCThreads 选项的值以增加并行标记线程的数量。
Also, increasing the heap is another option that would reduce the likelihood of evacuation failures.此外,增加堆是减少疏散失败可能性的另一种选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.