JVM 垃圾收集算法
{Back to Index}

Table of Contents

1 引用计数法

由于引用计数法含有循环引用和性能问题,JVM 并未选择此算法用于垃圾回收。

2 标记清除法(Mark-Sweep)

标记清除法先通过根节点标记所有可达对象,然后清除所有不可达对象。

该算法最大问题是产生空间碎片。

mark-sweep.png

Figure 1: 标记清除法工作原理

3 复制算法(Copying)

核心思想是将内存空间分为两块,每次只使用其中一块,在进行垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中去, 之后清除正在使用的内存块中的 所有对象 ,并交换两个内存块的角色。

复制算法的优势是效率高,回收后的内存空间没有碎片,但带来的 代价是内存折半。

basic-copy.png

Figure 2: 复制算法工作原理

3.1 JVM 对复制算法的改进

在 Java 新生代串行垃圾回收器中,使用了复制算法的思想。

新生代1分为 eden 区, from 区和 to 区 3 个部分。
其中 from 和 to 可以视为用于复制的两块 大小相同,地位相等且可进行角色互换的内存空间。 ( from 和 to 也称为 survivor 区)

在进行垃圾回收时, eden 区的存活对象会被复制到未使用的 survivor 区(假设是 to ),正在使用的 survivor 区(假设是 from )的存活对象也会被复制到 to 区。
大对象或者老年对象直接进入老年代 2 ,如果 to 区已满,对象也会直接进入老年代。
此时,eden 和 from 的剩余对象就是垃圾对象, 直接清空即可, to 则存放此次回收后的存活对象。

java-copy.png

Figure 3: 新生代串行垃圾回收器中使用的复制算法

4 标记压缩法(Mark-Compact)

标记压缩法是一种 适用于老年代 的回收算法,最终效果等同于标记清除法执行完成后在进行一次内存碎片整理。

mark-compact.png

Figure 4: 标记压缩法原理

Footnotes:

1

存放年轻对象的堆空间。年轻对象指刚刚创建的或经历垃圾回收次数不多的对象。

2

存放老年对象的堆空间。老年对象指经历多次垃圾回收后依然存活的对象。

Author: Hao Ruan (ruanhao1116@gmail.com)

Created: 2020-03-31 Tue 14:05

Updated: 2021-08-17 Tue 11:23

Emacs 27.1 (Org mode 9.3)