官网相关文档链接
Java虚拟机技术 Java Virtual Machine Technology
G1调优
G1的一个重点是为运行需要大量堆且GC延迟有限的应用程序的用户提供一个解决方案。这意味着堆大小约为6GB或更大,并且稳定且可预测的暂停时间低于0.5秒。
1)判断是否需要使用G1收集器?
官方描述 https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases
1、超过50%的Java堆内存被实时数据占用
2、对象分配或晋升的速度差异显著
3、长时间垃圾收集或压缩暂停(超过0.5到1秒)
2)不要手动设置新生代和老年代的大小,只要设置整个堆的大小
官方描述:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#sthref51
G1收集器在运行过程中,会自己调整新生代和老年代的大小。
其实是通过adapt代的大小来调整对象晋升的速度和年龄,从而达到为收集器设置的暂停时间目标,
如果手动设置了大小就意味着放弃了G1的自动调优。
3)设置GC最大暂停时间
一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置成50ms就不太合理。暂停时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。暂停时间只是一个目标,并不能总是得到满足。
-XX:MaxGCPauseMillis=20
4)MixedGC 调优
Mix GC 混合回收,针对正常的新生代垃圾收集和部分老年代region进行回收。
- 调整IHOP阈值
参数调小,会提前触发mix gc,频繁进行并发收集会浪费CPU资源(gc没有垃圾可回收导致cpu做无用功)。
参数太高,导致转移空间不足,频繁发生Full gc。
// 设置并发GC时堆内存占用百分比阈值,默认45,当heap中占用超过45%,触发mix gc
-XX:InitiatingHeapOccupancyPercent=45
- 调整并发线程数
当mix gc周期过长时,可增加标记线程的数量提高效率,注意线程数量不是越多越好。
IHOP如果阀值设置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果阀值设置过低,就会使标记周期运行过于频繁,并且有可能混合收集期回收不到空间。IHOP值如果设置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高ConcGCThreads。
-XX:ConcGCThreads=n
- 调整混合收集次数
参数调小,会增加每次混合收集的region数量,导致stop-the-world时间增加 。
// 并发运行期间,最多经历几次混合收集周期
-XX:G1MixedGCCountTarger=8
- 调整存活对象对分区Region占比
// 设置存活对象对Region占比,默认85%
-XX:G1MixedGCLiveThresholdPercent=85
// 设置CSet堆的总大小占比,默认10%
-XX:G1OldCSetRegionThresholdPercent=10
6)适当增加堆内存大小
-XX:MetaspaceSize=100M
-Xms6g
-Xmx6g