HotSpot虚拟机GC收集器全解析
·
一、HotSpot GC 总体架构概览
HotSpot 的 GC 并不是单一算法实现,而是一整套可组合的“收集器框架”,核心思想是:
不同区域(年轻代 / 老年代 / 元空间)使用不同的算法与收集器策略。
从宏观来看:
| 区域 | 典型算法 | 常见收集器 | 是否分代 |
|---|---|---|---|
| 年轻代(Young Gen) | 复制算法 (Copying) | Serial、Parallel Scavenge、G1 YGC、ZGC、Shenandoah | ✅ |
| 老年代(Old Gen) | 标记-整理 或 区域化疏散 | Serial Old、Parallel Old、CMS、G1 Old、ZGC、Shenandoah | ✅ |
| 元空间(Metaspace) | 类元数据的本地内存分配 | 无专门 GC(通过 ClassLoader 卸载释放) | ❌ |
这些收集器可以按代配对组合使用,比如:
- Serial + Serial Old
- Parallel Scavenge + Parallel Old
- ParNew + CMS
- G1(整堆统一)
- ZGC / Shenandoah(整堆统一,无明显分代界限)
二、HotSpot 主要收集器一览(按演进顺序)
1️⃣ Serial 收集器(单线程,基础款)
- 年轻代算法:复制 (Copying)
- 老年代算法:标记-整理 (Mark-Compact)
- 特点:
- 单线程:无论 CPU 几核,GC 线程只有 1 个。
- Stop The World(STW)全停顿:GC 时所有用户线程暂停。
- 优点:实现简单、开销小、吞吐高。
- 缺点:停顿长,不适合多核和大堆。
- 适用场景:单核或 Client 模式(JVM 默认选择)。
可视作 HotSpot 最原始、最纯粹的 GC 实现,后续所有收集器都基于此改进。
2️⃣ ParNew 收集器(Serial 的多线程版)
- 年轻代算法:复制 (Copying)
- 特点:
- 多线程版本的 Serial,其他机制几乎一致。
- 可以与 CMS 搭配使用(因为 CMS 需要并发的年轻代收集器)。
- 适用场景:搭配 CMS 时代的主流选择(JDK 8 之前)。
3️⃣ Parallel Scavenge / Parallel Old(吞吐量优先型)
Parallel Scavenge(年轻代)
- 算法:复制
- 目标:最大化吞吐量(用户代码运行时间 / 总时间)
- 特点:
- 自动调节堆大小、Eden:Survivor 比例、GC 频率。
- 通过参数
XX:MaxGCPauseMillis、XX:GCTimeRatio等控制平衡。 - 与 G1 不同,它不关注延迟,而关注总产出效率。
Parallel Old(老年代)
- 算法:标记-整理
- 多线程化的老年代收集器。
- 与 Parallel Scavenge 搭配,组成 高吞吐组合。
适用场景:
批处理、后台计算、大堆非交互系统(如 Spark、Hadoop、服务端定时任务等)。
4️⃣ CMS(Concurrent Mark-Sweep)收集器(低延迟时代的过渡产物)
CMS 是第一个真正的并发收集器,目标是减少老年代停顿。
-
年轻代:通常搭配 ParNew。
-
老年代算法:标记-清除 (Mark-Sweep)。
-
主要阶段:
- 初始标记 (Initial Mark):STW,仅标记 GC Roots 直接可达对象。
- 并发标记 (Concurrent Mark):应用线程与 GC 并发执行,标记可达对象。
- 重新标记 (Remark):STW,修正并发期间变动的对象引用。
- 并发清除 (Concurrent Sweep):清理不可达对象,和应用并发进行。
-
优点:
- 大部分阶段并发执行,停顿时间短。
-
缺点:
- 不整理 → 内存碎片化严重;
- 存在“浮动垃圾”;
- 并发失败可能退化为 Full GC(STW 标记整理)。
-
典型参数:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=70
注意
CMS 在 JDK 14 被正式移除,被 G1 彻底取代。
5️⃣ G1(Garbage First)收集器(分区 + 并发 + 可控延迟)
G1 是 CMS 的继任者,也是现代 HotSpot 默认收集器。
基本思想:
- 把整个堆划分为若干等大小的 Region(区域)。
- 不再物理区分年轻代 / 老年代,而是逻辑划分。
- 优先回收“垃圾比例最高”的区域(Garbage-First)。
算法混合特征:
- 年轻代:复制(Eden + Survivor 区之间疏散)
- 老年代:标记-整理(通过 Region 疏散实现无碎片)
- 支持并发标记(SATB)、可预测停顿目标(
XX:MaxGCPauseMillis)。
回收阶段:
- 初始标记(STW)
- 并发标记
- 最终标记(STW)
- 筛选回收(Mixed GC):混合回收年轻代 + 部分老年代区域。
优点:
- 无需全堆停顿;
- 无碎片;
- 可控停顿时间;
- 吞吐/延迟平衡良好。
参数示例:
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=45
适用场景:
中大型堆(4G~几十GB)、对延迟有一定要求的服务端程序。
6️⃣ ZGC(Z Garbage Collector)(并发压缩、极低延迟)
ZGC 是 “次世代” 收集器,几乎全流程并发,目标:<1ms 停顿。
核心机制:
- Region 化(ZPage):动态大小的区域。
- Colored Pointer(着色指针):用对象引用的高位比特表示对象状态(如标记、重定位中等)。
- Load Barrier(加载屏障):在每次读引用时,自动修正指针到新位置,实现并发重定位。
- 无碎片、无长停顿:所有阶段并发执行,仅短暂 STW 初始标记。
算法:
- 并发标记
- 并发重定位
- 并发引用处理
特性:
- 支持超大堆(TB 级)
- 停顿时间与堆大小解耦
- JDK 17+ 默认支持 分代 ZGC(Generational ZGC)
参数:
-XX:+UseZGC
-XX:SoftMaxHeapSize=8G
适用场景:
延迟敏感型(在线游戏、大型 Web 服务、金融交易系统等)。
7️⃣ Shenandoah GC(Red Hat 主导,JDK 12+)
也是低延迟收集器,与 ZGC 类似,但实现不同。
-
算法:Region + 并发标记 + 并发压缩。
-
实现:
- 采用 Brooks Pointer(转发指针)。
- 借助 读/写屏障实现并发对象移动。
-
目标:停顿时间 <10ms,与堆大小弱相关。
-
对比 ZGC:
特性 ZGC Shenandoah 指针方案 着色指针 转发指针 厂商 Oracle Red Hat 延迟 极低(1ms) 很低(几ms) 吞吐 略高 略低
三、收集器关系图谱(总结)
┌───────────────────┐
│ Serial (单线程) │
└────────┬──────────┘
│
┌──────────────┴──────────────┐
│ │
┌──────▼───────┐ ┌──────▼───────┐
│ ParNew + CMS│ │Parallel系列 │
│(并发标记清除)│ │(吞吐量优先) │
└──────────────┘ └──────────────┘
│
▼
┌──────┐
│ G1 │ (区域化 + 并发标记整理)
└──────┘
│
▼
┌───────────────┬───────────────┐
│ ZGC │ Shenandoah │
│ (并发压缩) │ (转发指针) │
└───────────────┴───────────────┘
四、HotSpot 收集器演进结论
| 收集器 | 核心算法 | 并发性 | 目标 | 状态 |
|---|---|---|---|---|
| Serial | 标记-整理 / 复制 | ❌ | 简单/小堆 | 历史 |
| Parallel | 标记-整理 / 复制 | ✅ | 吞吐优先 | 活跃 |
| CMS | 标记-清除 | ✅ | 低延迟 | 已移除 |
| G1 | 区域化 + 并发标记整理 | ✅ | 延迟/吞吐平衡 | 默认 |
| ZGC | 并发标记 + 并发重定位 | ✅✅ | 极低延迟 | 推荐 |
| Shenandoah | 并发标记 + 并发压缩 | ✅✅ | 低延迟 | 可选 |
更多推荐


所有评论(0)