为什么我的系统在大促期间,频繁fullgc?
前置知识
- 一般来说,我们的老年代大小,一般设置为堆内存大小的2/3,年轻代一般设置为堆内存大小的1/3,而年轻代里面一般分为伊甸园区,S0区和S1区,这三个的比例一般按年轻代大小的8:1:1进行分配。
- 正常来讲,对象先进入伊甸园区,然后进入S0(或S1)区,年龄加1,然后进入S1(或S0区)年龄再加1,在S区反复存活够15岁,便进入老年代,最终老年代如果满了,就会触发FullGc。
- 但是有一些条件下,对象会直接从伊甸园区进入老年代,例如:
大多数是这种情况,根据年龄进入老年代
下面这种情况,要适当调整8:1:1的比例,尽量让朝生夕死的大对象在年轻代里,通过minorgc(或younggc)回收掉,来避免频繁fullgc。
下面这种情况,这里暂时了解即可。
预估请求每秒产生的对象大小
对象流转过程分析
解决思路
我可以通过jstat命令,确定每次当前伊甸园区移到s0或s1区的对象的大小,然后有两种思路来解决这个问题:
1.调小老年代大小,同时调大年轻代大小,使每次流转到s0的对象大小达不到s0的50%,就能解决这个问题。
2.老年代大小不变,改变年轻代的8:1:1的比例,例如,这里我把比例改成6:1:1,也可以解决动态年龄判断这个问题。
愿你走出半生,归来仍是少年!