JVM 的垃圾回收(Garbage Collection, GC)主要分为 分代回收模型 下的不同垃圾回收器(Garbage Collectors),每种回收器针对不同场景设计。以下是常见的垃圾回收器分类及其特点:
1. 按工作模式分类
垃圾回收器 | 特点 | 适用场景 |
---|---|---|
Serial 收集器 | 单线程执行 GC,全程 Stop-The-World(STW) | 客户端应用、资源受限环境(如嵌入式) |
Parallel(吞吐量优先)收集器 | 多线程并行执行 GC,追求高吞吐量(-XX:+UseParallelGC ) | 后台计算、批处理任务 |
CMS(Concurrent Mark-Sweep)收集器 | 并发标记清除,减少 STW 时间(-XX:+UseConcMarkSweepGC ) | 对延迟敏感的老年代回收(JDK 9 前) |
G1(Garbage-First)收集器 | 分区化堆内存,可预测停顿时间(-XX:+UseG1GC ,JDK 9+ 默认) | 大内存、低延迟要求的应用 |
ZGC(Z Garbage Collector) | 基于染色指针和读屏障,STW 极短(-XX:+UseZGC ,JDK 15+ 生产可用) | 超大堆(TB 级)、超低延迟 |
Shenandoah 收集器 | 类似 ZGC,通过 Brooks 指针实现并发压缩(-XX:+UseShenandoahGC ) | 低延迟、高吞吐量混合场景 |
2. 按分代模型分类
JVM 堆内存通常分为 新生代(Young Generation) 和 老年代(Old Generation),不同区域使用不同回收策略:
新生代回收器
- Serial:单线程复制算法(Minor GC)。
- ParNew:多线程版 Serial,配合 CMS 使用。
- Parallel Scavenge:多线程复制算法,追求吞吐量。
老年代回收器
- Serial Old:单线程标记-整理算法(Major GC)。
- Parallel Old:多线程标记-整理算法,配合 Parallel Scavenge。
- CMS:并发标记-清除算法(减少 STW,但可能产生内存碎片)。
- G1/ZGC/Shenandoah:不分代或逻辑分代,统一处理全堆。
3. 核心算法
不同回收器基于以下算法实现:
- 标记-清除(Mark-Sweep)
- 标记存活对象,清除未标记对象(CMS 使用)。
- 缺点:内存碎片化。
- 标记-整理(Mark-Compact)
- 标记存活对象后,整理到内存一端(Serial Old、Parallel Old 使用)。
- 优点:避免碎片。
- 复制算法(Copying)
- 将存活对象复制到新区域(新生代 Survivor 区使用)。
- 优点:无碎片,但内存利用率低。
4. 如何选择垃圾回收器?
场景需求 | 推荐回收器 |
---|---|
小型应用、低资源消耗 | Serial / Serial Old |
高吞吐量(如后台计算) | Parallel Scavenge + Parallel Old |
低延迟(如 Web 服务) | G1 / CMS(JDK 8) |
超大堆内存、极致低延迟 | ZGC / Shenandoah |
5. 参数示例
# 使用 G1 回收器(JDK 8+)
-XX:+UseG1GC# 使用 ZGC(JDK 11+)
-XX:+UseZGC# 设置最大堆内存和停顿时间目标(G1)
-Xmx4g -XX:MaxGCPauseMillis=200
总结
- Serial/Parallel/CMS:适用于传统分代模型。
- G1:平衡吞吐量和延迟,JDK 9+ 默认。
- ZGC/Shenandoah:面向未来,适用于超大堆和亚毫秒级停顿。
选择合适的垃圾回收器需结合 应用性能需求(吞吐量、延迟)、堆内存大小 和 JDK 版本 综合评估。