JVM的垃圾回收算法

JVM有四种垃圾回收算法:

  • 标记清除算法(Mark-Sweep)
  • 复制算法(copying)
  • 标记整理算法(Mark-Compact)
  • 分代收集算法(Generational)

标记清除算法(Mark-Sweep):

标记清除算法分为两个阶段:

1、通过可达性分析,标记出所有需要回收的对象。

2、回收被标记的对象所占用的空间。

优点:实现简单、不需要对象进行移动。

缺点:标记、清除过程效率低,产生大量不连续的内存碎片,提高了垃圾回收的频率。

复制算法(copying):

为了解决清除算法效率不高的问题,产生了复制算法。

把内存空间划分为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用的区域,把存活对象复制到另一个区域中,最后将当前使用的区域的可回收的对象进行回收。

优点:按顺序分配内存即可,实现简单、运行高效、不用考虑内存碎片。

缺点:可用的内存大小缩为原来的一半,对象存活率高时会频繁进行复制。

标记整理算法(Mark-Compact):

标记整理算法,与标记清除算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使用它们紧凑的排列在一起,然后对端边界以外的内存进行回收。回收后,已用和未用的内存都各自一边。

优点:解决了标记清理算法存在的内存碎片问题。

缺点:仍需要进行局部对象移动,一定程度上降低了效率。

分代收集算法(Generational):

当前商业虚拟机都采用分代收集的垃圾收集算法。分代收集算法是根据对象的存活周期将内存划分为几块。一般包括新生代(年轻代)、老年代和永久代。新生代基本采用复制算法,老年代和永久代采用标记整理算法。

在新生代中使用复制算法,但是在老年代就不能选择复制算法了,因为老年代的对象存活率会较高,这样会有较多的复制操作,导致效率变低。而标记清除算法在老年代中的效率不高,在内存回收后容易产生大量内存碎片。因此老年代使用标记整理算法。