一、引言
在Java应用运行过程中,垃圾回收(Garbage Collection, GC)是内存管理的核心机制,直接影响程序性能。JVM提供了多种垃圾回收器,适用于不同场景。本文将系统梳理主流垃圾回收器的工作原理、适用场景及选型策略。
二、GC核心概念
- 分代收集:堆内存分为新生代(Young Generation)和老年代(Old Generation),采用不同回收策略。
- STW(Stop-The-World) :GC执行时暂停所有应用线程,时间长短直接影响响应速度。
- 吞吐量(Throughput) :单位时间内应用代码执行时间占比。
- 延迟(Latency) :单次GC导致的应用停顿时间。
三、垃圾回收器分类
分类维度 | 类型 | 代表回收器 |
---|---|---|
工作线程数 | 单线程/多线程 | Serial vs Parallel |
工作模式 | 并发/并行 | CMS vs G1 |
内存碎片处理 | 压缩/非压缩 | Serial(压缩) vs CMS(非压缩) |
四、主流垃圾回收器详解
1. Serial 回收器
-
特点:单线程、简单高效,适合客户端应用。
-
工作流程:
新生代(复制算法) → 老年代(标记-整理算法)
-
适用场景:内存小(百MB级)、无低延迟要求的场景。
2. Parallel Scavenge(吞吐量优先)
- 特点:多线程并行回收,关注吞吐量。
- 参数示例 :
-XX:MaxGCPauseMillis=100
(目标最大停顿时间)
-XX:GCTimeRatio=99
(GC时间占比不超过1%) - 适用场景:后台计算、批处理任务。
3. CMS(Concurrent Mark-Sweep)
-
四阶段流程:
- 初始标记(STW)
- 并发标记
- 重新标记(STW)
- 并发清除
-
缺点:内存碎片、CPU敏感。
-
适用场景:Web服务等要求低延迟的系统(JDK 8及之前)。
4. G1(Garbage-First)
-
核心机制:
- 堆划分为多个Region(1MB~32MB)
- 优先回收垃圾最多的区域(Garbage-First)
-
Mixed GC模式:同时回收新生代和部分老年代。
-
优势 :可预测停顿(
-XX:MaxGCPauseMillis
)。 -
适用场景:JDK 9+默认回收器,适合6GB以上内存。
5. ZGC(低延迟之王)
-
关键技术:
- 染色指针(Colored Pointers)
- 并发压缩(<1ms STW)
-
内存支持:TB级堆内存,JDK 15后正式支持。
-
适用场景:超低延迟(如金融交易系统)。
6. Shenandoah
- 特点:与ZGC类似,但通过Brooks指针实现并发压缩。
- 优势:JDK 12+支持,Red Hat贡献。
- 适用场景:需要低延迟且使用OpenJDK的中间件。
五、对比与选型指南
回收器 | 线程模式 | 压缩策略 | 最大堆内存 | 适用场景 |
---|---|---|---|---|
Serial | 单线程 | 压缩 | 数百MB | 客户端/嵌入式 |
Parallel | 多线程 | 压缩 | 数GB | 吞吐量优先任务 |
CMS | 并发 | 非压缩 | 4-8GB | JDK8 Web服务 |
G1 | 并发 | 局部压缩 | 数十GB | JDK9+默认,平衡场景 |
ZGC | 并发 | 压缩 | 4TB+ | 亚毫秒延迟,JDK15+ |
选型建议:
- 优先JDK版本:JDK11+首选G1,JDK17+优先考虑ZGC。
- 吞吐量场景:Parallel Scavenge/Old。
- 低延迟要求:ZGC(STW<1ms)或 Shenandoah。
- 超大堆内存:ZGC/Shenandoah支持TB级堆。
六、参数调优示例
bash
# 启用G1回收器
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
# 启用ZGC(JDK15+)
-XX:+UseZGC
-XX:+ZUncommitDelay=300 # 自动返还内存给OS
七、总结
理解不同GC的工作原理是性能优化的基石。随着JDK版本迭代,ZGC/Shenandoah等新回收器正在重新定义Java的内存管理极限。建议开发者根据应用特点(堆大小、延迟要求、JDK版本)选择最优方案,并持续关注GC技术的演进。
延伸阅读:
- Oracle官方GC调优指南
- 《深入理解Java虚拟机》第3章(周志明著)