Java垃圾回收算法

 

1. 复制算法(应用在新生代)

步骤

优势

劣势

2.标记清除算法(老年代)

步骤

优势

劣势

3.标记整理算法(老年代)

步骤

优势

劣势

4.分代回收算法(理论)

分代回收的理论

JVN在进行垃圾回收时常常使用以下几种垃圾回收算法:

1. 复制算法(应用在新生代)

Java垃圾回收算法

步骤

  • Eden/FromSurvivor复制到ToSurvivor,年龄+1

当Eden区域空间占满时会触发第一次MinorGC将存活的对象拷贝到FromSurvivor区域,当Eden区域再次触发MinorGC时会扫描Eden和From两个区域进行垃圾回收,经过这次垃圾回收后还存活的对象会被复制到To区域(如果对象的年龄已经到了老年代的标准,则直接进入到老年区),同时把这些对象的年龄+1。

  • 清空Eden/FromSurvivor区域

清空Eden和From区域,这时就是两个Survivor区域的交换,此时谁空谁就是To区域。

  • ToSurvivor和FromSurvivor区域互换

互换Survivor区域,原来的ToSurvivor成为下次GC时的From区域。部分对象会在From区域和To区域来回复制,直到复制到15此(有JVM的-XX:MaxTenuringThreshold=n的n决定,默认是15次),最终如果对象年龄大于15次,将被划分到老年代区域。

优势

实现简单 

劣势

需要将空间等分成两份,每次使用其中的一份,用完后将存活对象复制到另一个空间。造成空间浪费。

Java垃圾回收算法

JVM在进行新生代垃圾回收时,认为新生代的对象都是朝生夕灭的,所以将两个空间的大小划分为8:2(1From+1To),使用复制算法进行新生代的垃圾回收算法支持。

2.标记清除算法(老年代)

Java垃圾回收算法

步骤

  1. 标记出垃圾对象
  2. 统一清除待回收的垃圾对象

优势

整个堆都可以进行对象的内存分配,不会造成空间的浪费。

劣势

  1. 效率低:标记和清除两个阶段都需要把全部对象扫描一遍,这个过程是很耗时间的。
  2. 内存碎片:经历标记清除后堆内会有很多的内存碎片产生,会导致大对象在进行内存分配时无法找打连续可用的空间。

3.标记整理算法(老年代)

Java垃圾回收算法

步骤

  1. 标记出垃圾对象
  2. 将存活对象往一端移动,直接清理末端垃圾数据即可

优势

  1. 空间不浪费:整个堆都可以进行对象的内存分配,不会造成空间的浪。
  2. 空间统一整理,不会产生内存碎片。
  3. 相对标记清除耗时短,只需要在标记阶段进行全堆扫描。

劣势

会进行对象移动,实现相对复杂

对象移动会增加回收成本,增加耗时和复杂度;不移动对象会增加内存的分配成本

4.分代回收算法(理论)

分代回收的理论

  1. 绝大部分对象都是朝生夕灭的
  2. 熬过回收次数越多的对象越难收集

按照对象年龄的不同将堆区域划分为新生代和老年代,根据各区域对象特征不同采用不同的垃圾回收算法,这就是分代回收算法。