我一直在查看来自jstat(-gc选项)的日志,发现我们的应用程序花费了大量时间进行新一代收集。
我们将最大堆大小设置为 16gigs(无最小值)。
这些是根据 jstat 日志的初始容量:
S0C: 2112S1C: 2112EC: 17024OC: 63872
在一天的其余时间里,S0C,S1C,EC都没有增加,即使我们似乎有大量的新一代事件并花费大量时间进行。但是,旧容量会增加。
我通过设置 -XX:NewSize=6G 在 UAT 中运行了比较测试,应用程序的性能要好得多(新一代事件很少,总体上在 GC 中的时间要少得多)
我的问题是:为什么新一代容量没有随着我们原来的设置而增加?我最初是否必须分配更多内存?
我们正在使用 JVM Hotspot 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。
我建议启用详细的 GC 日志记录,并查看它对次要世代的作用。