最近我将我的Java应用从CMS + ParNew切换到了G1GC。 当我进行切换时,我观察到CPU使用率上升了,GC计数和暂停时间也增加了。 在切换之前,我的JVM标志是
java -Xmx22467m -Xms22467m -XX:NewSize=11233m -XX:+UseConcMarkSweepGC -XX:AutoBoxCacheMax=1048576 -jar my-application.jar
转换后我的标志是:
java -Xmx22467m -Xms22467m -XX:+G1GC -XX:AutoBoxCacheMax=1048576 -XX:MaxGCPauseMillis=30 -jar my-application.jar
我遵循了 Oracle 的最佳实践http://www.oracle.com/technetwork/tutorials/tutorials-1876574.html。
Do not Set Young Generation Size
并没有设置年轻代的大小。
然而,我怀疑年轻代大小是问题所在。
我看到堆使用量在6-8 GB之间波动。
相比之下,使用CMS和Par New时,内存使用量在4-16 GB之间增长,只有在这种情况下才会看到GC:
我不确定为什么使用G1GC时GC如此频繁。当涉及到G1GC的GC调优时,我不确定自己漏掉了什么。
我正在使用Java 8: Java版本“1.8.0_144” Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
感谢您的帮助。
更新:
关于这些暂停的更多信息:
你可以看到所有这些暂停都是G1New,而且它们似乎与我的目标暂停时间相同,即30毫秒。
当我看到在切换到G1GC之前的ParNew暂停时,情况是这样的:
所以它们也都是年轻代集合(ParNew),但它们不太频繁且较短,因为它们仅在堆使用量达到约14GB时发生(根据图表)
我仍然不知道为什么G1New会这么早发生(就堆使用而言)
更新2: 我还注意到NewRatio=2,我不知道G1GC是否尊重它,但这意味着我的新生代被限制在7GB。这可能是原因吗?
更新3 添加G1GC GC日志: https://drive.google.com/file/d/1iWqZCbB-nU6k_0-AQdvb6vaBSYbkQcqn/view?usp=sharing