最近观察到有一个service做full GC 比较频繁,决定对它进行调优,先整理一下GC的知识。
GC分类
GC分为两类:minor GC 和 full GC
minor GC:对新生代进行的GC操作。通常采用复制算法,将Eden Space 以及survivor Space 0的不可回收对象复制到survivor Space 1。
触发条件:当Eden Space空间不足时。
full GC:对老年代进行的GC操作。通常采用标记-清除算法,即将不可回收对象做上标记,回收其它未被标记对象,这样做有一个缺点,会产生大量内存碎片。
对象衰老:每当对象经过一次minor GC, 该对象的年龄加1,当超过某个年龄的时候,该对象就会被移到老年代空间。当老年代空间不足时,就会发生full GC。
触发条件:
- 每次经过minor GC后被移到老年代的对象平均大小大于当前老年代的剩余空间时会触发一次full GC。
- 如果有连续大对象需要分配内存,当经过一次minor GC后,Eden Space仍然不能容纳这些大对象,这些对象就会直接进入老年区,当老年区也无法容纳这些大对象时,就会触发full GC。
- 当经过一次minor GC后,survivor space无法容纳当前仍存活的对象,这些对象就会直接进入老年区, 当老年区也无法容纳这些大对象时,就会触发full GC。
- 在代码里调用system.gc()。