1588 字
8 分钟
JVM 三大垃圾回收算法:标记-清除、标记-复制与标记-整理

面试题:JVM 常见的垃圾回收算法有哪些?

主要有三种:

  1. 标记-清除(Mark-Sweep)
  2. 标记-复制(Mark-Copy)
  3. 标记-整理(Mark-Compact)

它们解决的都是同一个问题:找到存活对象后,如何处理不再存活的对象所占用的内存。

注意:垃圾回收算法是回收内存的思路,垃圾收集器是具体实现这些思路的程序。

标记-清除算法#

基本原理#

分为两个阶段:

  1. 标记:找出所有存活对象并做标记。
  2. 清除:清理没有被标记的对象所占用的内存。

示意图:

回收前:
[A存活] [B垃圾] [C存活] [D垃圾] [E存活]
标记后:
[A存活] [B垃圾] [C存活] [D垃圾] [E存活]
清除后:
[A存活] [ 空闲] [C存活] [ 空闲] [E存活]

优点#

  • 实现相对简单。
  • 不需要移动存活对象。
  • 在存活对象较多、移动成本较高的场景中有一定优势。

缺点#

容易产生内存碎片。

例如,内存中有很多零散的小空闲区域。即使空闲内存总量足够,也可能没有一块连续空间能满足较大的内存分配请求。

记忆口诀#

标记垃圾以外的存活对象,再清理垃圾;不移动对象,但可能产生内存碎片。

标记-复制算法#

基本原理#

将内存划分为两个区域,通常一次使用一个区域。

  1. 在当前区域中分配对象。
  2. GC 时找出存活对象。
  3. 将存活对象复制到另一个区域。
  4. 清空原来的区域。
  5. 后续可以交换两个区域的角色。

示意图:

回收前:当前区域
[A存活] [B垃圾] [C存活] [D垃圾]
复制存活对象:
另一个区域
[A存活] [C存活] [ 空闲 ]
清空原区域:
[ 全部空闲 ]

优点#

  • 回收后存活对象集中排列。
  • 不容易产生内存碎片。
  • 分配内存时可以顺序移动指针,分配过程简单。

缺点#

  • 需要额外的空间存放复制后的对象。
  • 存活对象越多,需要复制的数据通常越多,回收成本也可能越高。

典型应用#

传统分代收集设计中的新生代常采用复制思路。

例如,传统新生代通常包含 Eden、Survivor 0 和 Survivor 1。对象在年轻代 GC 中存活时,会被复制到 Survivor 区或晋升到老年代。

注意:实际 JVM 收集器的区域组织和具体实现可能不同,不是所有收集器都严格使用两个等大的空间。

记忆口诀#

把存活对象搬到另一边,再清空原区域;回收后整齐,但需要额外空间。

标记-整理算法#

基本原理#

同样先标记存活对象,但不会把它们复制到另一块独立区域。

  1. 标记所有存活对象。
  2. 将存活对象向内存的一端移动。
  3. 清理边界以外的内存。

示意图:

回收前:
[A存活] [B垃圾] [C存活] [D垃圾] [E存活]
整理后:
[A存活] [C存活] [E存活] [ 空闲 ]

优点#

  • 回收后存活对象集中。
  • 能有效减少内存碎片。
  • 不必像复制算法那样始终准备一整块独立的目标空间。

缺点#

  • 移动对象需要额外开销。
  • 对象移动时,需要正确维护相关引用,处理过程相对复杂。

典型应用#

传统分代收集设计中,老年代常采用标记-整理思路,因为老年代对象通常存活时间较长,存活对象比例可能较高。

但这只是常见设计,并不是所有老年代收集器都使用标记-整理。

记忆口诀#

把存活对象标记出来,移动到一端,清理剩余空间;减少碎片,但需要移动对象。

三种算法对比#

对比项标记-清除标记-复制标记-整理
核心操作清理垃圾复制存活对象移动存活对象
是否移动对象否是是
是否容易产生碎片是否否
额外空间需求通常较少需要目标空间通常不需要独立的等大目标区
主要开销标记与清理标记与复制标记与移动
常见适用思路部分收集场景传统新生代传统老年代

面试回答模板#

问:JVM 常见的垃圾回收算法有哪些?

答:

JVM 常见的垃圾回收算法有标记-清除、标记-复制和标记-整理。

标记-清除先标记存活对象,再清理未存活对象,优点是不需要移动对象,但容易产生内存碎片。

标记-复制将存活对象复制到另一个区域,再清空原区域,优点是回收后内存连续、分配简单,但需要额外空间。

标记-整理先标记存活对象,再将它们移动到内存的一端并清理剩余空间,能够减少内存碎片,但移动对象会带来额外开销。

实际 JVM 会根据不同的内存区域、对象存活情况和收集器设计,选择或组合不同的算法。

需要记住的重点#

  • 标记-清除:不移动对象,容易产生内存碎片。
  • 标记-复制:复制存活对象,需要额外空间。
  • 标记-整理:移动存活对象,减少内存碎片。
  • 算法没有绝对优劣,需要根据场景选择。
  • 垃圾回收算法不等于垃圾收集器。

自测题#

题目 1#

哪种算法不移动存活对象,但容易产生内存碎片?

答案:标记-清除算法。

题目 2#

为什么复制算法通常需要额外空间?

答案:因为需要把存活对象复制到另一个区域,原区域随后才能被整体清空。

题目 3#

哪种算法通过移动存活对象来减少内存碎片?

答案:标记-整理算法。

题目 4#

标记-复制算法和标记-整理算法的主要区别是什么?

答案:复制算法把存活对象搬到另一个区域;整理算法则把存活对象移动到当前内存区域的一端。

JVM 三大垃圾回收算法:标记-清除、标记-复制与标记-整理
https://blog.xqcherry.top/posts/interview/jvm/gc-algorithms/
作者
xqcherry
发布于
2026-10-09
许可协议
CC BY-NC-SA 4.0