Sunday面试指南

JVM 垃圾回收算法有哪些?标记清除、复制和标记整理有什么区别?

下面是一段教学用的模拟面试。

🧑‍💻 面试官:已经知道哪些对象还活着,接下来怎么回收空间?

🙋‍♂️ 我:可以清掉死对象,也可以把活对象挪到一起。

🧑‍💻 面试官:如果只清掉死对象,剩下的空位分散得很小,能放下一块大对象吗?

🙋‍♂️ 我:空闲总量够,也可能没有一段足够大的连续空间。

🧑‍💻 面试官:那移动对象要付什么成本?复制算法是复制所有对象,还是只处理仍存活的对象?

本题不再问“谁能回收”,而是问:「怎样把可回收空间变成好用的空间」。

面试速答(60 秒版)

标记清除、复制和标记整理,是理解垃圾回收如何处理空间的几种基础办法,不是三个必须二选一的收集器品牌。

标记清除先识别存活对象,再回收未存活对象占用的空间,通常不移动存活对象,但可能留下外部碎片。

复制算法把存活对象迁移到目标空间,再回收相应来源空间。它可以让目标布局更紧凑,但需要迁移成本和足够的目标空间;经典半区复制要预留另一半,实际收集器不一定按整个堆一分为二。

标记整理则在确定存活对象后,计算并调整位置,把对象集中,得到更连续的空闲区,也要处理对象移动和引用更新。

实际收集器会组合不同办法,并考虑对象存活率、堆布局、暂停、并发与吞吐。分代是利用寿命差异安排回收的策略,不是另一种单独的“搬运算法”。

三种垃圾回收算法对存活对象和空闲空间的不同安排

知识点详解:同一排内存,用三种办法整理

先给三个算法一份相同的输入

假设一个简化内存区域,依次放着 A、B、C、D、E、F。为方便比较,假设每个对象占一个同样大的槽位。

已经通过存活判断知道 A、C、F 仍然需要保留,B、D、E 可以回收。

接下来不再重复 GC Roots 的定义,而是看怎样处理这片空间。真实堆对象大小不同,引用和并发也更复杂;这个假设只用于解释空间布局。

标记清除:把不需要的位置变成空闲

保留 A、C、F,把 B、D、E 占据的位置回收。

结果可能是:A、空位、C、两个连续空位、F。存活对象还在原来的位置,新的空闲块散落在它们中间。

如果现在要分配一个需要三个连续槽位的对象,总空闲量虽然有三个,却没有一段三个连续空位能直接满足它。

这就是外部碎片带来的问题。不是说所有空闲都不能用,也不是说采用清除就一定立刻分配失败;分配器还能管理不同大小空闲块,但碎片确实会影响可用性。

空闲够多,不一定放得下

复制:把活对象放到另一片空间

先准备一片目标空间,把 A、C、F 复制过去,并更新相关引用,让程序之后找到新位置。

目标中变成 A、C、F 紧凑排列,后面留下连续空闲。来源中已经迁移的那部分对象不再需要按原布局保留,可以相应回收。

注意,复制的主线是迁移存活对象,不是把 B、D、E 这些死对象也搬过去,再在新空间重做一遍清理。Cornell 的复制回收讲解用来源与目标两区展示了这个关系。

如果活对象很少,迁移工作可能比较少;如果大部分对象都活着,需要搬的内容也会多。目标空间不足怎么办,同样要有实际收集器的处理办法。

经典半区模型预留两区轮换,便于教学,却不能扩展成“所有现代 JVM 的整个堆都只能使用一半”。

标记整理:在当前回收范围里集中存活对象

标记整理同样从 A、C、F 的存活集合出发,但通常不要求把整个范围按经典半区复制方式分成两个对等区域。

它要确定存活对象的新位置,移动它们,并处理引用更新。最后,存活对象集中到一端,后面形成较大的连续空闲区域。

Cornell CS4120 讲义区分了清除、整理与复制的基础过程。具体实现可以优化扫描次数与信息存放方式,不能把一种教学步骤说成所有 JVM 必须逐字照做。

因此,整理改善了碎片问题,但不是免费。移动数据、更新引用和协调正在运行的程序,都需要成本。

两种集中,空间安排不同

为什么新生代经常会讲复制,但不能只背口诀?

HotSpot GC 基础文档介绍了一个常见观察:很多对象的寿命较短。

如果某个区域中只有少量对象仍然活着,迁移少量存活对象再回收剩余空间,可能比较合适。但这是基于负载特征的策略,不是程序保证每个对象都短命。

长寿命对象多时,频繁搬动大量存活内容的收益可能下降。实际收集器还会处理跨区域引用、对象晋升、大对象等问题。

所以,面试可以先讲存活率怎样影响迁移量,再讲具体收集器。不要只背“年轻代复制、老年代清除”,就把所有版本和收集器都归进固定两格。

算法、分代、收集器和暂停,分别是哪一层?

基础算法描述怎样回收或迁移空间;分代描述根据对象寿命安排回收范围;具体收集器把这些办法和实现细节组合起来。

是否 Stop-The-World、哪些阶段并发执行、使用多少线程,则要看具体算法实现与阶段。不能从“叫标记”直接推导全程暂停,也不能从“并发收集器”推导从来没有暂停。

选择具体收集器时,先看实际暂停分布、分配速率、存活量和内存限制。背全名字不如说明当前瓶颈是什么,再提出可验证的调整。

本题用空间模型讲基础算法,不提供 TS/Python 小程序冒充 JVM GC 实现。模型可检查布局变化,不能据此证明实际收集器性能。

面试官继续追问

对象移动后,原来的引用会不会指向错地方?

收集器必须协调引用更新或通过具体访问机制处理迁移,不能把它画成对象搬走、引用永远留在原地。细节取决于收集器。

清除不用搬对象,就一定最快吗?

不一定。还要看标记、扫描、空闲管理和后续分配的成本。没有某种办法对所有负载都最快。

标记整理就完全不需要额外内存吗?

不能说完全不需要。它仍然可能需要标记与位置等辅助信息;只是空间安排不同于经典半区复制。

面试速记卡

  • 本题起点:存活集合已确定,比较怎样释放和整理空间。
  • 标记清除:回收死对象位置,存活对象不主动集中,可能留碎片。
  • 复制:迁移活对象到目标空间,需要目标容量与引用处理。
  • 标记整理:集中存活对象,改善连续空闲,但移动有成本。
  • 层次:算法、分代、具体收集器与暂停阶段不能混成一个概念。

公司面试真题

真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。

  • 美团 · 开发(含 AI 项目追问) · 原帖未明确批次

    垃圾回收有哪些基本算法?(题意整理)

    美团面经 ↗
    原帖发布于 2025-09-09

  • 美团 · Java后端 · 实习

    垃圾回收有哪些算法?(题意整理)

    4.21美团Java实习一二面面经 ↗
    面试记录为 2020-04-21、2020-04-24;原帖编辑于 2020-11-14

  • 京东 · Java后台 · 校招

    JVM 使用哪些垃圾回收算法?(题意整理)

    京东 Java 后台三面凉经 ↗
    原帖编辑于 2019-08-23(历史校招面经)

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历