分代垃圾回收是基于对象存活周期的垃圾回收算法。Java虚拟机将堆内存划分为新生代和老年代,根据不同的垃圾回收算法对不同代进行回收。
新生代:存放刚刚创建的对象,每次垃圾回收时会回收大部分对象。
老年代:存放在新生代通过垃圾回收演变来的对象,垃圾回收频率低。
分代垃圾回收的工作原理:
- 大部分对象在新生代中快速死亡,每次GC会回收大量对象,新生代的内存利用率较低。
- 新生代内存使用达到一定比例时,Minor GC会对新生代进行垃圾回收。
- 对象在新生代SURVIVE若干次GC后,会被放入老年代。
- 老年代对象死亡速度慢,垃圾回收频率较低,内存利用率较高。
- 当老年代使用达到一定比例时,Major GC会对整个堆进行垃圾回收。
- 老年代对象数量过多时,会使用” remembered set “记录新生代中引用老年代对象的关联,加速Major GC。
应用分代收集算法的主要垃圾回收器有:
Parallel Scavenge收集器:新生代收集器,Minor GC使用复制算法。
CMS收集器:老年代收集器,Major GC使用标记清除算法。
G1收集器:将堆内存划分为多个区域,按新生代和老年代方式进行回收。
来看一个简单例子:
public class GCDemo {
public static void main(String[] args) {
byte[] data1 = new byte[2*1024*1024]; // 新生代2MB
data1 = null; // 一次Minor GC,data1可回收
byte[] data2 = new byte[2*1024*1024]; // 经历过Minor GC,放入老年代
data2 = null; // 老年代对象,下次Major GC可回收
}
}
执行该程序:
- 分配2MB新生代对象data1,此时新生代已满,触发Minor GC,data1被回收。
- 分配2MB新生代对象data2,data2经过Minor GC存活,会被晋升到老年代。
- data2变为不可达,要等到下次Major GC才会被回收。