📌 PDF :大白话说Java面试题 --- 02-JVM篇
第20题:垃圾收集算法和垃圾收集器有什么区别
📚 回答:
-
核心区别:
- 垃圾收集算法 是内存回收的方法论,提供理论基础(如如何标记、回收、整理内存)。
- 垃圾收集器 是对这些方法论的具体实现,依赖算法完成实际回收,并可能结合多种算法针对不同内存区域优化。
-
一句话总结:算法是"思路",收集器是"落地产品"。
1. 垃圾收集算法
-
定义 :
垃圾收集算法是指导垃圾回收的核心思想,不涉及具体实现细节,只定义回收步骤与策略。
-
常见算法详解:
-
标记-复制(Copying)
- 步骤:将内存分为两块(Eden + Survivor),只使用其中一块,存活对象复制到另一块,然后清空原区域。
- 优点:无碎片,分配速度快(指针碰撞)。
- 缺点:内存利用率低(最多用一半,或通过 Survivor 比例优化)。
- 适用:年轻代(对象朝生夕灭)。
-
标记-清除(Mark-Sweep)
- 步骤:标记所有存活对象,然后清除未标记对象。
- 优点:简单,不需要移动对象。
- 缺点:产生大量内存碎片,导致大对象无法分配,可能提前触发 Full GC。
- 适用:老年代(如果配合 CMS 使用)。
-
标记-整理(Mark-Compact)
- 步骤:标记存活对象后,将所有存活对象向一端移动,然后清理边界外内存。
- 优点:无碎片,内存规整。
- 缺点:移动对象开销大,需暂停应用(STW 时间长)。
- 适用:老年代(如 Serial Old、Parallel Old)。
-
-
算法选择原则:
- 年轻代适合复制算法(存活率低)。
- 老年代适合标记-清除或标记-整理(存活率高,避免频繁复制)。
2. 垃圾收集器
-
定义 :
垃圾收集器是 JVM 提供的具体回收组件,实现了一种或多种垃圾收集算法,并可能包含并发、并行、分代等特性。
-
常见垃圾收集器详解(JDK 8~21):
-
Serial / Serial Old
- 单线程回收,回收时会 STW。
- 适合客户端模式或单核 CPU、小堆内存(<100MB)。
-
Parallel Scavenge + Parallel Old
- 多线程回收,注重吞吐量(CPU 时间用于应用 vs 回收)。
- 适合后台计算、批处理任务。
- 参数:
-XX:MaxGCPauseMillis、-XX:GCTimeRatio。
-
CMS(Concurrent Mark Sweep)
- 并发标记清除,低延迟。
- 缺点:产生碎片、浮动垃圾、CPU 敏感。
- JDK 9 起废弃,JDK 14 移除。
-
G1(Garbage First)
- 分区域(Region)管理内存,可预测停顿时间模型。
- 混合使用复制与标记-整理(局部复制,全局逻辑无碎片)。
- 适合堆内存 ≥4GB,追求平衡吞吐与低延迟。
-
ZGC
- 低延迟(<10ms),并发整理,支持 TB 级堆内存。
- 通过染色指针、读屏障、并发重映射实现。
- JDK 15 起正式可用。
-
Shenandoah
- 类似 ZGC,并发压缩,低延迟。
- OpenJDK 项目,非 Oracle JDK 默认包含。
-
-
收集器与算法的对应关系:
- G1:局部用复制算法,全局逻辑类似标记-整理(无碎片)。
- CMS:标记-清除 + 并发处理。
- ZGC:染色指针 + 并发标记-整理(部分)。
3. 区别与联系详解
| 对比维度 | 垃圾收集算法 | 垃圾收集器 |
|---|---|---|
| 抽象层级 | 理论/策略 | 实现/产品 |
| 是否可执行 | 不可直接执行 | 可直接运行 |
| 是否依赖具体内存布局 | 否 | 是(分代、Region 等) |
| 如何选择 | 由收集器决定 | 开发者或 JVM 自适应选择 |
| 举例 | 复制、标记-清除、标记-整理 | Serial、Parallel、G1、ZGC |
| 是否产生碎片 | 部分算法会 | 由算法决定,但收集器可额外优化 |
4. 面试官常追问与回答模板
-
Q1:算法和收集器的关系是什么?
A:算法是解决"怎么做"的理论,收集器是"谁来做、何时做、做多快"的具体实现。同一算法可以被不同收集器使用。
-
Q2:如何选择垃圾收集器?
A:
- 吞吐量优先 → Parallel GC。
- 低延迟(<100ms)→ G1(堆 4-32GB)。
- 超低延迟(<10ms)+ 大堆(>32GB)→ ZGC / Shenandoah。
- 小内存(<100MB)+ 单核 → Serial。
-
Q3:G1 用的是哪种算法?
A:G1 混合使用多种算法:年轻代用复制,老年代用并发标记 + 选择性复制(类似标记-整理效果)。
-
Q4:为什么 CMS 被废弃?
A:因为无法彻底解决碎片问题,浮动垃圾可能导致 Full GC(Serial Old),且 CPU 敏感,不如 G1 可控。
-
Q5:ZGC 为什么几乎没有 STW?
A:通过染色指针(自愈)、读屏障、并发重映射等技术,让对象访问时修正引用,避免大范围暂停。
5. 大厂面试加分项(可选深挖)
- 分代假说:弱分代假说(朝生夕灭) → 年轻代用复制;强分代假说(越老越可能存活) → 老年代用整理/清除。
- 停顿 vs 吞吐取舍:并发收集器(CMS、G1、ZGC)会占用应用线程 CPU,降低吞吐量,但减少停顿。
- 全收集(Full GC)触发条件:老年代空间不足、Metaspace 满、System.gc()、晋升失败、碎片导致分配大对象失败等。
💡 最终面试官期望的总结(可背诵):
"垃圾收集算法是内存回收的理论步骤,如复制、标记-清除、标记-整理;垃圾收集器是 JVM 实现这些算法的具体组件,如 G1、ZGC。算法决定'正确性',收集器决定'性能特征'。选型需根据延迟、吞吐、堆大小、CPU 核心数综合判断。"
觉得对您有帮助,麻烦 点点关注啦 ,您的关注是我创作的最大动力~ 🎯