关于full gc的优化思路
方案一
增大内存
增大内存是解决full gc最快的方案之一
好处:降低了真正full gc 延迟的概率,(虽然产品每隔半小时主动full gc,但是随着内存的增大,老年代使用率在半小时内超过90%的概率就少了,就会导致每次的full gc 比较快的完成。大大降低了full gc的高延迟发生。)
坏处:当老年代用满时,做一次full gc的耗时会提升。如果在某一时刻sql查询量非常大,导致了full gc,此时单次的full gc时长就会增加。
方案二
调整full gc的间隔
调整full gc的间隔,由30min 调整为10min;缩短时间间隔,因为在正常情况下短时间内老年代的使用率超过90%的概率比较小,或者说短时间内在老年代利用率不是太高的时候就主动做一次full gc,这样虽然full gc的频次增加,但是每次full gc时垃圾回收的量降低了,这样full gc高延迟的状况也会有很大改善。
方案三
增大年轻代内存,降低老年代内存,同时控制进入老年代对象的大小
此做法可以避免大的对象过多进入老年代引发full gc,增大年轻代,减少老年代主要目的是让垃圾回收尽量的发生在年轻代,即使老年代发生full gc也能短时间恢复服务。
可以通过以下参数设置
-XX:NewSize #设置Yong Generation的初始值大小
-XX:Maxnewsize #设置Yong Generation的最大值大小
-XX:G1HeapRegionSize #增大该参数,使得巨型对象可以分布在一个region上,在垃圾回收时候不在跨region回收。
-XX:NewRatio #默认值是2,Old Generation是 Yong Generation的2倍,即Yong Generation占据内存的1/3 ,官网建议不能低于1,即 老年代和年轻代对内存大小设置一致。
-XX:PretenureSizeThreshold 直接晋升到老年代的对象大小,设置这个参数后
大于这个参数的对象将直接在老年代分配,可以通过调大这个参数,使得老年代分配较少的对象。
方案四
关闭每隔半小时自动full gc的策略,通过老年代使用占比触发full gc
关闭每隔半小时自动full gc的策略,默认情况下,当老年代的使用率超过90%才会做一次full gc,我们可以通过调低这个值来减少full gc时候回收的垃圾大小。
-XX:+UseCmsInitiatingOccupancyOnly #只根据老年代空间占用率来决定何时启动垃圾回收线程 (这个参数还有待商榷,不知道是否使用G1 )
方案五
减少停顿时间,增大垃圾回收吞吐量
停顿时间:垃圾收集器做垃圾回收中断应用执行的时间。XX:MaxGCPauseMillis #默认值是200,可以试着减半
吞吐量:垃圾收集的时间和总时间的占比:1/(1+n),吞吐量为1-1/(1+n)。-XX:GCTimeRatio=n
-XX:ParallelGCThreads:指定GC工作的线程数量