JVM垃圾回收器常见的组合和各自的特点
一、新生代与老年代垃圾回收器的组合
新生代回收器 | 老年代回收器 | 适用场景 | JDK 默认版本 |
---|---|---|---|
Serial | Serial Old | 单线程客户端应用、低资源环境 | JDK 1.3~8(客户端模式) |
ParNew | CMS | 低延迟 Web 服务、响应优先系统 | JDK 5~8(需手动启用) |
Parallel Scavenge | Parallel Old | 高吞吐量后台任务(计算密集型) | JDK 7~8(服务端模式默认) |
G1 | G1 自身管理分代 | 大堆内存、低延迟、动态分代 | JDK 9+(服务端模式默认) |
二、各组合核心特点
1. Serial + Serial Old
新生代(Serial):
- 单线程复制算法(Stop-The-World,STW)。
- 简单高效,无线程交互开销。
老年代(Serial Old):
- 单线程标记-整理算法(STW)。
适用场景:
- 客户端应用(如 Swing 桌面程序)、嵌入式设备。
- 缺点:STW 时间长,不适用于服务端大堆内存。
2. ParNew + CMS
新生代(ParNew):
- 多线程复制算法(STW),与 Serial 兼容。
老年代(CMS):
- 多线程并发标记-清除算法(Concurrent Mark Sweep)。
- 四阶段:初始标记(STW)→ 并发标记→ 重新标记(STW)→ 并发清除。
适用场景:
- Web 服务、API 服务器(追求低延迟,容忍内存碎片)。
- 缺点:CPU 敏感,内存碎片可能导致 Full GC 退化(需压缩)。
3. Parallel Scavenge + Parallel Old
新生代(Parallel Scavenge):
- 多线程复制算法(STW),吞吐量优先。
老年代(Parallel Old):
- 多线程标记-整理算法(STW)。
适用场景:
- 批处理、科学计算(如 Hadoop 离线任务)。
- 缺点:STW 时间不可控,不适合低延迟场景。
4. G1(Garbage-First)
分代管理:
- 逻辑分代:仍保留新生代(Eden/Survivor)和老年代(Old)。
- 物理划分:将堆划分为多个大小固定的 Region(1MB~32MB),动态分配为 Eden/Survivor/Old/Humongous(大对象区)。
回收机制:
- Young GC:回收新生代 Region(STW)。
- Mixed GC:同时回收新生代和部分老年代 Region(STW),基于停顿预测模型。
- Full GC:退化时触发(单线程整理,类似 Serial Old)。
特点:
- 低延迟:通过 Region 回收和停顿预测控制 STW 时间(默认 200ms)。
- 大堆友好:适合 4GB 以上堆内存。
- 内存整理:Mixed GC 阶段并行整理,减少碎片。
适用场景:
- 现代服务端应用(如微服务、云原生环境)。
三、关于 G1 的疑问解答
Q: G1 没有老年代了吗?
A: 不是。G1 仍然有老年代,但分代方式与传统回收器不同:
- 逻辑分代保留:对象年龄(Age)达到阈值后晋升到老年代。
- 物理 Region 动态分配:老年代由多个 Region 组成,不要求连续内存。
- 混合回收(Mixed GC) :选择性回收高垃圾比例的老年代 Region,避免全堆扫描。
四、对比总结
回收器组合 | 吞吐量 | 延迟 | 内存碎片 | 适用堆大小 |
---|---|---|---|---|
Serial + Serial Old | 低 | 高 | 低 | <100MB |
ParNew + CMS | 中 | 低 | 高 | 2~4GB |
Parallel Scavenge | 高 | 中 | 低 | 2~8GB |
G1 | 中高 | 低 | 低 | >4GB |
五、选择建议
- 小堆 & 客户端:Serial + Serial Old。
- 中等堆 & 低延迟:ParNew + CMS(JDK 8 及之前)。
- 大堆 & 高吞吐:Parallel Scavenge + Parallel Old(计算密集型)。
- 大堆 & 低延迟:G1(JDK 9+ 首选)或 ZGC/Shenandoah(超大堆+极低延迟)。
版权申明
本文系作者 @Tis-FYM 原创发布在Tis-FYI站点。未经许可,禁止转载。
评论