GC(分配失败)[PSYoungGen]

3
最近我们将代码从java7切换到了java8。我们在PSYoungGen中每10分钟都会出现GC分配失败的情况。我们甚至尝试了使用-XX:NewSize和-XX:NewMaxSize开关,将其设置为5GB(总堆大小为10GB)。但即使在gc分配失败后,PSYoungGen仍会触发到接近5GB的大小。这是添加的一些日志:
[GC (Allocation Failure) [PSYoungGen: 3145728K->114922K(3670016K)] 3145728K->115026K(5767168K), 0.2511084 secs] [Times: user=0.26 sys=0.14, real=0.25 secs]
[GC (Allocation Failure) [PSYoungGen: 4443141K->125893K(4718592K)] 4443261K->126229K(6815744K), 0.2318927 secs] [Times: user=0.42 sys=0.22, real=0.24 secs]

在一个答案中:Java GC(分配失败)与此相关,我看到这是正常的行为,只是想知道是否有办法克服这个问题?谢谢。


主要的GC消耗只在年轻代中发生,而不在老年代中。我们总共为堆分配了10 GB,其中5GB用于年轻代。 - Bhaskar
我所质疑的是,即使您将新设置为5Gb,我认为(https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/sizing.html)使用默认的“SurvivorRatio”为“8”,我认为会留下大约1.25Gb的幸存者空间,剩下3.75 Gb的伊甸园。您是否可能分配接近此大小的对象? - David
1
关于“没有这样的日志”,在您的原始帖子中,您链接到的答案中,被采纳的回答者发表了评论:“旧版JVM不会为次要GC周期打印GC原因。”。因此,或许一直都发生了这种情况,只是直到现在才知道。 - David
谢谢David,我认为这些日志将作为新JVM的一部分存在。关于对象的分配,我会进行检查。感谢您的评论。 - Bhaskar
没问题,我会转移到回答中。如果有帮助的话,如果您能标记为已接受,我们将不胜感激。 - David
显示剩余5条评论
2个回答

3
我认为你设置的NewSize可能控制着整个新生代的大小(包括Eden和Survivor空间),因此你的Eden空间可能仍然不足以直接分配新的大对象(例如大型byte[])。
我的疑问是,即使你将新生代设置为5Gb,我认为Oracle文档建议使用默认值SurvivorRatio8将大约留下1.25Gb的Survivor空间,剩下3.75 Gb的Eden。你是否可能分配超过或接近这个大小的对象?
至于没有这样的日志记录,在你的OP中链接到的答案中,被接受的答案发表了以下评论:
“旧版JVM没有打印GC的原因。”
所以也许这一直在发生,只是你现在才知道。

0

使用

-XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent

这将解决您的问题。
如果您使用垃圾优先(G1)垃圾收集器,我们建议将ExplicitGCInvokesConcurrent属性添加到启动参数列表中。这样可以减少在垃圾收集进行时应用程序暂时不可用的可能性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接