为什么java ParNew年轻代集合会降级为使用CMS的单CPU?

时间:2017-06-07 14:55:06

标签: java garbage-collection

我一直无法找到关于年轻集合的哪个阶段实际序列化到单个CPU的解释。我的猜测是,在老一代中进行第一次拟合(最适合?)搜索时。

从我能够收集的内容来看,我们看到的可怕性能与伊甸园的大小相关,我们最终会不必要地将大量数据复制到老一代。

我们在年轻的GC中基本上停止了这个过程,并且有时一分钟或者CPU利用率下降到大约1个CPU。我们没有看到证据表明我们实际上由于碎片而无法在旧一代中进行分配。

我们在32台CPU机器上使用-XX:+ UseConcMarkSweepGC -XX:+ UseParNewGC,16GB或31GB堆。 Java 7和Java 8(u66)都有。升级有助于此吗?

1 个答案:

答案 0 :(得分:0)

我已经找到了解决我的GC问题的方法,并了解发生了什么,但不确切地知道ParNew young GC的哪一部分实际上被序列化到单个CPU。

事实证明,如果您使用的是CMS,那么即使在新的Java 8上也不会使用NewRatio,2的文档默认值。只需在命令行中指定-XX:NewRatio = 2就可以完全取消我们的31GB堆ElasticSearch实例上的GC地狱。 "这不是一个错误,它是一个功能"解释在这里:http://bugs.java.com/view_bug.do?bug_id=8153578

我们获得的年轻尺寸是1.4GB,而不是我们从默认NewRatio预期的~10GB。因此,在高线程数的情况下,即使我们有足够的内存,年轻数据仍被视为终身。

与此相关,我们注意到线程池的现象,例如ElasticSearch。对于通常会运行的典型8-12个线程,eden大小足够大,但如果负载增加,我们就会下降到GC地狱。因此,如果您有一个带有线程池的服务器,则eden大小调整需要基于所有线程都在使用的情况。