Java GC(分配失败)


129

为什么总是“ GC(分配失败)”?

适用于linux-amd64 JRE(1.8.0_25 -b17)的Java HotSpot(TM)64位服务器VM(25.25- b02),

CommandLine flags: 
-XX:CMSInitiatingOccupancyFraction=60 
-XX:GCLogFileSize=10485760 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:InitialHeapSize=32212254720 
-XX:MaxHeapSize=32212254720 
-XX:NewRatio=10 
-XX:OldPLABSize=16 
-XX:ParallelGCThreads=4 
-XX:+PrintGC 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintStringTableStatistics 
-XX:+PrintTenuringDistribution 
-XX:StringTableSize=1000003 
-XX:SurvivorRatio=4 
-XX:TargetSurvivorRatio=50 
-XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops
-XX:+UseParNewGC 
-XX:+UseConcMarkSweepGC
27.329: [GC (Allocation Failure) 27.329: [ParNew
Desired survivor size 44728320 bytes, new threshold 15 (max 15)
- age   1:   16885304 bytes,   16885304 total
: 349568K->16618K(436928K), 0.2069129 secs] 349568K->16618K(31369920K), 0.2070712 secs] [Times: user=0.78 sys=0.04, real=0.21 secs]


28.210: [GC (Allocation Failure) 28.210: [ParNew
Desired survivor size 44728320 bytes, new threshold 15 (max 15)
- age   1:   28866504 bytes,   28866504 total
- age   2:   12582536 bytes,   41449040 total
: 366186K->47987K(436928K), 0.2144807 secs] 366186K->47987K(31369920K), 0.2146024 secs] [Times: user=0.84 sys=0.01, real=0.22 secs]


29.037: [GC (Allocation Failure) 29.038: [ParNew
Desired survivor size 44728320 bytes, new threshold 2 (max 15)
- age   1:   28443488 bytes,   28443488 total
- age   2:   28386624 bytes,   56830112 total
- age   3:   12579928 bytes,   69410040 total
: 397555K->76018K(436928K), 0.2357352 secs] 397555K->76018K(31369920K), 0.2358535 secs] [Times: user=0.93 sys=0.01, real=0.23 secs]

Answers:


202

“分配失败”是导致GC周期开始的原因。

“分配失败”意味着在Eden中没有剩余空间来分配对象。因此,这是年轻GC的正常原因。

较早的JVM不会打印GC的原因,因为GC周期较小。

“分配失败”几乎仅是次要GC的可能原因。次要GC启动的另一个原因可能是CMS备注阶段(如果+XX:+ScavengeBeforeRemark启用)。


1
谢谢。只是发现旧的JVM不会显示“分配失败”。
user3644708 2015年

2
我没有完全得到这个答案,所以应该避免吗?“这是年轻GC的正常原因”。那么年轻的GC是错误的选择吗?
托马斯

7
是的,这是正常现象
Alexey Ragozin

183
对于一天通常会发生多次的事件,GC(分配失败)的字词选择不当。那些JVM工程师应该更频繁地出去工作,并尝试在现实世界中进行社交,以便他们可以学习人们理解的更友好的术语。
萨尔瓦多·瓦伦西亚

79
@SalvadorValencia没关系,定期读取GC日志的人也不是完全“正常”的。:)
biziclop

8

“分配失败”是GC踢不正确的原因。这是GC操作的结果。

当没有空间可分配时,GC将启动(取决于执行次要或主要GC的区域)。执行GC后,如果释放的空间足够好,但是如果空间不足,则会失败。分配失败就是这样的失败之一。下面的文件有很好的解释 https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc.html


1
“(...)然后发生分配失败(因为没有空间从正在撤离的区域分配活动对象),并且完成了世界停止状态(STW)的完整收集。” -在Java 1.8服务器模式下,我重现了短暂的停顿,并将这两个跟踪记录一起打印:[GC(分配失败)2287742K-> 1148645K(2633216K),0.4571912秒] [完整GC(人体工程学)1148645K-> 1112141K (3184128K),2.8563984秒]。因此,我支持您的回答;-)
何塞·曼努埃尔·戈麦斯·阿尔瓦雷斯

-10

当在jdk1.8中使用CMS GC时会出现此错误,我更改G1 Gc解决了此问题。

 -Xss512k -Xms6g -Xmx6g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=70 -XX:NewRatio=1 -XX:SurvivorRatio=6 -XX:G1ReservePercent=10 -XX:G1HeapRegionSize=32m -XX:ConcGCThreads=6 -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 

1
为什么这被否决了很多次?一个解释将是有用的。
Mike Stoddart,

2
因为就像说您在Rust中重写了程序,现在却没有这样的消息?
Simplylizz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.