在上一篇文章中,我们深入探讨了 JVM 的类加载机制与自定义类加载器的实现,为理解字节码运行时的生命周期奠定了坚实基础。接下来,我们将进入 JVM 性能调优的核心领域之一——垃圾收集器(Garbage Collector, GC)。
GC 是 JVM 实现自动内存管理的关键模块,选择合适的 GC 策略与参数不仅影响吞吐量和延迟,还关乎系统的可预测性和稳定性。本文将从架构、特点、适用场景等多个维度,全面对比 JVM 中最具代表性的四类收集器:Serial、CMS、G1 和 ZGC。
一、为什么要了解多个 GC 收集器?
JVM 提供了多种垃圾收集器,不同 GC 的算法模型、并发能力和停顿特性各不相同。选错 GC 不仅无法充分发挥硬件潜力,还可能引发以下问题:
- 响应时间抖动
- Full GC 频繁触发
- 老年代空间耗尽
优秀的 GC 选择与配置能大幅优化吞吐率与稳定性,是每个高级开发者必须掌握的核心技能。
二、主流垃圾收集器快速导航
收集器 | 算法 | 并发 | 停顿 | 适用场景 |
---|---|---|---|---|
Serial | 复制 / 标记清除 | 无 | STW,单线程 | Client、小堆、单核 |
CMS | 标记-清除 | 并发标记 | 短停顿 | Web、低延迟服务 |
G1 | 分区整理 | 并发标记 | 可控停顿 | 大堆、混合场景 |
ZGC | 并发标记-整理 | 全并发 | 毫秒级停顿 | 超低延迟、大内存应用 |
三、Serial GC:最简单的单线程收集器
✦ 回收算法
- 新生代采用复制算法
- 老年代使用标记-清除
✦ 特点
- 所有阶段单线程执行
- 每次 GC 都会完全 Stop-The-World(STW)
- 实现简单、资源占用低
✦ 优劣分析
优点 | 缺点 |
---|---|
吞吐率尚可 | 无并发、暂停时间长 |
适合资源受限环境 | 不适合响应敏感业务 |
✦ 典型场景
- 嵌入式设备
- 小型单机服务(< 100MB 堆)
✦ 启动方式
-XX:+UseSerialGC
四、CMS(Concurrent Mark Sweep):并发回收的先驱
✦ 回收算法
- 年轻代采用 ParNew(多线程复制)
- 老年代使用标记-清除,分阶段并发执行
✦ 回收阶段
- Initial Mark(STW)
- Concurrent Mark
- Remark(STW)
- Concurrent Sweep
✦ 优劣分析
优点 | 缺点 |
---|---|
老年代大部分并发,STW 短 | 无整理,容易碎片化 |
多线程回收,适合多核 | 需预留空间防止 promotion failed |
响应好于 Serial | 并发模式失败会触发 Full GC(单线程) |
✦ 使用建议
- 使用
-XX:CMSInitiatingOccupancyFraction=70
控制触发阈值 - 启用
-XX:+UseCMSInitiatingOccupancyOnly
避免动态调节
✦ 启动方式
-XX:+UseConcMarkSweepGC
⚠️ 注:CMS 已在 JDK 14 被移除,建议迁移至 G1 或 ZGC。
五、G1(Garbage First):现代化的分区回收器
✦ 核心理念:Region 化 + 并发预测停顿
- 堆划分为多个大小一致的 Region
- 年轻代 / 老年代不再是物理区块,而是动态 Region 集合
✦ 回收阶段
- Young GC:回收 Eden + Survivor(STW)
- Mixed GC:Eden + 部分 Old(STW + 并发标记支持)
✦ 优劣分析
优点 | 缺点 |
---|---|
支持并发标记,预测 STW 时间 | 调优参数较多 |
减少 Full GC 频率 | Mixed GC 过程复杂 |
自动整理,避免碎片 | 初始配置成本较高 |
✦ 启动方式
-XX:+UseG1GC
✦ 调优建议
-XX:MaxGCPauseMillis=200
控制最大停顿目标(毫秒)-XX:G1HeapRegionSize=4m
调整 Region 粒度-XX:InitiatingHeapOccupancyPercent=45
控制 Mixed GC 触发
推荐生产环境默认选择 G1,适配性强。
六、ZGC(Z Garbage Collector):毫秒级延迟革新
✦ 特点概览
- 所有回收阶段(标记、整理、重定位)几乎全并发
- 停顿时间控制在 <10ms
- 支持 4TB+ 堆(JDK 17 支持最多 16TB)
✦ 回收机制
- 借助 Load Barrier 技术,实现对象引用的原位标记
- 避免传统 GC 对对象指针的大规模调整
✦ 优劣分析
优点 | 缺点 |
---|---|
超低延迟,适合 RT < 10ms 场景 | 不支持 JDK 8,需 JDK 11+ |
完整并发回收 + 整理 | 对 CPU 敏感,吞吐略低 |
内存碎片率极低 | 可视化支持弱于 G1(需配合 JFR) |
✦ 启动方式(JDK 11+)
-XX:+UseZGC
配合:-Xms4G -Xmx4G
固定堆配置更稳定
七、收集器横向对比总结
特性对比 | Serial | CMS | G1 | ZGC |
---|---|---|---|---|
并发能力 | ❌ 无 | ✅ 老年代并发 | ✅ 全堆并发 | ✅ 全阶段并发 |
STW 时长 | 长 | 短(部分) | 中等可控 | 极短(<10ms) |
吞吐能力 | 中等 | 高 | 高 | 中 |
内存整理 | ❌ 否 | ❌ 否(碎片) | ✅ 是 | ✅ 是 |
容量支持 | 小堆 | 中堆 | 大堆(>8G) | 超大堆(TB 级) |
适用场景 | 小应用 | 响应优先 | 大部分应用 | 实时系统、大数据、高频交易 |
推荐版本 | JDK 8- | JDK 8-13 | JDK 11+ | JDK 17+(推荐) |
八、收集器演进趋势与选择建议
- 新项目优先选择 G1(默认 GC),高可控、适配性好
- 对延迟极度敏感(金融交易、实时游戏)可尝试 ZGC
- JDK 8 老项目仍可用 CMS,但应考虑升级计划
- Serial 仅适用于测试、嵌入式、低配置容器场景
Java 的 GC 机制从单线程到多线程,再到 Region 化、指针隔离与可预测低延迟,是面向未来服务架构的演进路线。
✅ 总结 · 专业视角回顾
- 每种 GC 收集器都有其特定使用场景和调优策略;
- G1 是当前推荐的通用 GC,具备平衡延迟与吞吐的能力;
- CMS 逐步退出历史舞台,ZGC 与 Shenandoah 是面向实时的现代方案;
- 理解各收集器的算法原理 + 日志特征 + 参数控制,是进行性能优化和系统稳定保障的基础。
📌 下一篇预告
下一篇《第 5 篇:GC 日志全面解析与性能分析实战》将深入 GC 日志结构与字段,教你如何通过日志定位 GC 瓶颈、优化应用停顿、分析对象生命周期,内容更贴近实战与故障排查。
👍 如果你觉得本文有用:
- 点赞是对我最大的鼓励 💪
- 收藏备用,作为你 GC 调优的速查宝典 🧠
- 关注专栏,持续更新 JVM 性能实战系列
- 欢迎评论区留言交流你实际使用过的 GC 经验!