- 单线程,适用于小内存客户端。
- 新生代:复制算法,老年代:标记-整理算法。
- STW 时间较长,适合单核 CPU。
- 参数:-XX:+UseSerialGC
- 多线程版 Serial,适用于配合 CMS 使用。
- 新生代:复制算法,多线程并行收集。
- 老年代仍使用 Serial Old 或 CMS。
- 参数:-XX:+UseParNewGC
- 关注吞吐量,适合后台计算任务。
- 新生代:复制算法,老年代:标记-整理算法。
- 可配置最大停顿时间和吞吐量目标。
- 参数:-XX:+UseParallelGC
- 并发标记清除,低停顿,内存碎片问题严重。
- 四个阶段:初始标记(STW)、并发标记、重新标记(STW)、并发清除。
- JDK9 标记为废弃,JDK14 移除。
- 参数:-XX:+UseConcMarkSweepGC
- 区域化管理,预估停顿时间。
- 将堆划分为多个 Region,不要求连续。
- 可预测停顿时间:-XX:MaxGCPauseMillis=200
- 适合大堆内存(>6GB)。
- 参数:-XX:+UseG1GC
- 子代收集,低延迟,支持大堆内存。
- STW 时间 < 10ms,支持 TB 级堆。
- 使用染色指针和读屏障技术。
- 参数:-XX:+UseZGC
- 红帽贡献,低停顿并发压缩。
- STW 时间 < 10ms,与 ZGC 类似。
- 使用 Brooks Forwarding 指针。
- 参数:-XX:+UseShenandoahGC
- 支持分代,结合低延迟与吞吐量。
- 分为年轻代和老年代,减少扫描范围。
- 参数:-XX:+UseZGC -XX:+ZGenerational
- 不做任何垃圾收集,用于测试。
- 适合短生命周期的应用或性能测试。
- 参数:-XX:+UseEpsilonGC
- Eden 区满了:新对象分配时 Eden 区不足。
- TLAB 分配失败:线程本地分配缓冲区不足。
- 老年代空间不足:对象晋升或大对象分配时老年代不足。
- 方法区空间不足:元空间或永久代空间不足。
- 显式调用 System.gc():建议 JVM 执行 GC(不保证执行)。
- 堆转储时:jmap -dump 或 -XX:+HeapDumpOnOutOfMemoryError。
- CMS 失败:CMS 并发失败时退化为 Serial Old。
- G1 转移失败:G1 没有足够的空闲 Region。
- GC 期间所有应用线程暂停。
- 只有 GC 线程运行,无法响应请求。
| 收集器 | STW 时间 | 说明 |
|---|
| Serial | 长 | 单线程,适合小堆 |
| Parallel | 中 | 多线程,吞吐量优先 |
| CMS | 短 | 并发标记,减少 STW |
| G1 | 可控 | 可设置目标停顿时间 |
| ZGC | 极短 | < 10ms |
| Shenandoah | 极短 | < 10ms |
- 选择合适的收集器:低延迟场景选择 G1、ZGC。
- 调整堆大小:避免频繁 GC。
- 优化对象分配:减少临时对象,使用对象池。
- 调优 GC 参数:设置合理的停顿时间目标。
| 收集器 | 新生代 | 老年代 | STW | 适用场景 |
|---|
| Serial | Serial | Serial | 长 | 小内存、单核 |
| Parallel | Parallel Scavenge | Parallel Old | 中 | 多核、吞吐量优先 |
| CMS | ParNew | CMS | 短 | 低延迟(已淘汰) |
| G1 | G1 | G1 | 可控 | 大堆、平衡延迟和吞吐 |
| 收集器 | 新生代 | 老年代 | STW | 适用场景 |
|---|
| ZGC | ZGC | ZGC | 极短 | 超低延迟、超大堆 |
| Shenandoah | Shenandoah | Shenandoah | 极短 | 超低延迟、超大堆 |
| 特性 | 分代收集 | 非分代收集 |
|---|
| 内存布局 | 年轻代 + 老年代 | 统一内存区域 |
| 收集算法 | 复制 + 标记整理 | 标记-整理 |
| 吞吐量 | 高 | 中 |
| 延迟 | 中 | 极低 |
| 适用场景 | 通用场景 | 低延迟、大堆 |
- 分为标记和清除两个阶段。
- 优点:不需要额外空间。
- 缺点:产生内存碎片。
- 标记后将存活对象向一端移动。
- 优点:无内存碎片。
- 缺点:移动对象成本高。
- 将存活对象复制到另一块区域。
- 优点:无内存碎片,效率高。
- 缺点:需要双倍空间。
- 新生代使用复制算法。
- 老年代使用标记-整理或标记-清除算法。
- 优点:针对不同代的特点优化。