我一直在查看jstat(-gc选项)的日志,发现我们的应用程序花费了大量时间进行新一代收集。
我们将最大堆大小设置为16gigs(没有最小值)。
根据jstat日志,这些是初始容量:
S0C: 2112 S1C:2112EC:17024OC:63872
在一天的其余时间里,S0C、S1C、EC都没有增加,尽管我们似乎有大量的新一代事件并花了很多时间来做。然而,旧容量增加了。
我在UAT中通过设置-XX: NewSize=6G进行了比较测试,应用程序的性能要好得多(很少有新一代事件,总体GC时间要短得多)
我的问题是:为什么新的一代容量没有随着我们原来的设置而增加?是不是期望我最初必须分配更多的内存?
我们正在使用JVM热点1.6。
这是来自JVM默认值的新建的grep:
uintx MaxNewSize = 18446744073709486080{product}
intx NewRatio = 2 {product}
uintx NewSize = 1310720 {product}
uintx NewSizeThreadIncrease = 5320 {pd product}
intx PartialPeelNewPhiDelta = 0 {C2 product}
bool UseNewLongLShift = false {product}
bool UseParNewGC = false {product}
我对热点1.6的CMS人体工程学还不确定,但是如果你想让热点动态地移动年轻一代的边界,也许你必须启用自适应大小策略并调整相关选项。
或者升级到较新的JVM并尝试使用G1GC,它绝对支持自适应大小调整。
也可能是CMS没有为新一代使用完整的可用大小,否则它无法实现一些目标,例如次要的gc暂停时间目标。确保它为新一代使用多线程GC,而不是串行的。
我建议启用详细GC日志记录,并查看它对次要世代的作用。