Java 自动内存管理带来了便利,但在面试和线上调优时,GC 往往是绕不开的大山。
很多人背八股文时会感到割裂:一会儿是'标记清除算法',一会儿是'三色标记',一会儿又是'CMS/G1',它们到底是什么关系?
咱们试着从宏观视角切入,构建一张完整的 JVM 垃圾回收知识图谱。
一、基础概念梳理:从判定标准到回收策略
在深入探讨具体的算法实现之前,我们需要先理清 GC 体系的脉络。我们将从判定标准、回收策略、落地实现以及调优演进四个维度来拆解。
1. 判定标准:什么是垃圾?
GC 的首要任务是判断哪些对象是'存活'的,哪些是'垃圾'。
- 早期探索(引用计数法):通过计算对象被引用的次数来判断。但它有一个致命缺陷——无法解决循环引用(A 引用 B,B 引用 A,两者都无外部引用)导致的内存泄漏问题,因此已被现代 JVM 抛弃。
- 现代标准(根可达性算法):这是 Java 目前使用的核心法则。以一系列 GC Roots(如栈中引用的对象、静态变量等)为起点,沿着引用链向下搜索。凡是不可达的对象,无论它们之间是否有连接,均被视为垃圾。
2. 核心策略:垃圾回收算法
确定了垃圾之后,我们需要高效地清理它们。主流的基础算法有三种,它们各有优劣:
- 标记 - 清除 (Mark-Sweep):
- 特点:直接标记出垃圾并清除。
- 优点:速度快,基础简单。
- 缺点:会产生大量内存碎片,导致后续分配大对象时可能因无法找到连续空间而触发 GC。
- 标记 - 整理 (Mark-Compact):
- 特点:清除垃圾后,将存活对象向一端移动、整理。
- 优点:无内存碎片。
- 缺点:涉及对象的移动,效率相对较低。
- 复制算法 (Copying):
- 特点:将内存分为两块,每次只用一块。回收时将活对象复制到另一块,清空当前块。
- 优点:运行高效,且无内存碎片。
- 缺点:空间利用率低,需要占用双倍内存空间(以空间换时间)。
3. 管理思想:分代垃圾回收
在实际应用中,JVM 不会单一地使用某种算法,而是基于**'对象生命周期不同'这一事实,采用了分代管理**策略:
- 年轻代 (Young Gen):
- 特点:存放'朝生夕死'的对象,GC 频率极高。
- 策略:采用 复制算法。因为存活对象少,复制成本低,效率最高。
- 老年代 (Old Gen):
- 特点:存放生命周期长的对象,GC 频率较低。
- 策略:采用 标记 - 整理 或 标记 - 清除 算法。因为对象存活率高,不适合用复制算法(空间浪费且复制开销大)。
4. 落地执行:垃圾回收器
垃圾回收器是上述算法的具体实现者。不同的回收器适用于不同的业务场景:




