1、JDK版本
以下所有优化全部基于JDK8
版本,强烈建议低版本升级到JDK8
,并尽可能使用update_191
以后版本。
2、如何选择垃圾回收器
响应优先应用:面向C端对响应时间敏感的应用,堆内存8G以上建议选择G1,堆内存较小或低版本JDK选择CMS;
吞吐量优先应用:对响应时间不敏感,以高吞吐量为目标的应用(如MQ、Worker),建议选择ParallelGC
;
3、各回收器优化参数
1)基本参数配置(所有应用、所有回收器都需要):
shell
-Xmx(一般为容器内存的50%)
-Xms(与Xmx一致)
-XX:MetaspaceSize(通常256M~512M)
-XX:ParallelGCThreads=容器核数
-XX:CICompilerCount=容器核数(必须大于等于2)
2)ParallelGC
除以上参数外,一般不需要额外调优(JDK8默认回收器)
3)CMS
shell
-XX:+UseConcMarkSweepGC
-Xmn (一般为堆内存的三分之一),尤其是配置了ParallelGCThreads后必须配置此参数
-XX:ConcGCThreads=n(默认为ParallelGCThreads/4,可视情况调整至ParallelGCThreads/2)
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70(推荐值)
4)G1
shell
-XX:+UseG1GC
-XX:ConcGCThreads=n(默认为ParallelGCThreads/4,可视情况调整至ParallelGCThreads/2)
-XX:G1HeapRegionSize=8m(若堆内存在8G以内且有较多大对象推荐设置此值)
*注意不要设置-Xmn 和 XX:NewRatio
5)其他调优参数
-XX:+ParallelRefProcEnabled
如果GC时Reference
处理时间较长,例如大量使用WeakReference
对象,可以通过此参数开启并行处理
4、开启GC日志
shell
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/export/Logs/gc.log
5、如何判断GC是否正常
1)GC
是否频繁:YoungGC
频率一般几十秒钟一次,FullGC
一般每天几次,注意 G1
回收器不应该出现 FullGC
;
2)GC
耗时:耗时主要取决于堆内存大小及垃圾对象数量。YoungGC
时间通常应在几十毫秒,FullGC
通常在几百毫秒;
3)每次GC内存是否下降:应用刚启动时,每次YoungGC
内存应该回收到较低水位,随着时间推移老年代逐步增多,内存水位会逐步上涨,直到FullGC/MixedGC(G1)
,内存会再次回到较低水位,否则可能存在内存泄漏;
4)如果使用ParallelGC
,堆内存耗尽才会触发FullGC
,所以不用配置堆内存使用率告警,但需关注GC
频率;