Java 中的 Serial GC、Parallel GC、CMS、G1、ZGC 和 Shenandoah 是不同的垃圾收集器,各自基于不同的设计理念,适用于不同的应用场景。以下是它们的特点及适用场景分析:

1. Serial GC(串行垃圾收集器)

  • 特点
    • 单线程执行垃圾回收,回收时会暂停所有用户线程(Stop-The-World,STW)。
    • 实现简单,内存占用少,没有线程交互开销。
    • 采用"标记-复制"(新生代)和"标记-整理"(老年代)算法。
  • 适用场景
    • 单线程环境或客户端应用(如桌面程序)。
    • 内存较小的嵌入式系统。
    • 不适合服务器环境和高并发应用(STW 时间过长)。
  • 启用参数-XX:+UseSerialGC

2. Parallel GC(并行垃圾收集器)

  • 特点
    • 多线程执行垃圾回收,提高吞吐量(单位时间内处理的任务量)。
    • 仍有 STW 停顿,但停顿时间比 Serial GC 短。
    • 新生代采用"标记-复制",老年代采用"标记-整理"算法。
    • 关注吞吐量优化,默认会根据 CPU 核心数自动调整线程数。
  • 适用场景
    • 注重吞吐量的服务器应用(如后台计算、批处理任务)。
    • 多核 CPU 环境,允许一定 STW 停顿。
    • 不适合对响应时间敏感的应用(如 Web 服务)。
  • 启用参数-XX:+UseParallelGC(默认新生代并行)、-XX:+UseParallelOldGC(老年代也并行,JDK 8 后默认启用)

3. CMS(Concurrent Mark Sweep,并发标记清除)

  • 特点
    • 以低延迟为目标,尽量减少 STW 时间。
    • 老年代回收主要分为 4 个阶段:初始标记(STW)→ 并发标记 → 重新标记(STW)→ 并发清除。
    • 新生代仍使用 Parallel GC 的"标记-复制"算法。
    • 缺点:
    • 并发阶段会占用 CPU 资源,降低吞吐量。
    • 采用"标记-清除"算法,会产生内存碎片。
    • 对大堆内存支持不佳,可能因内存碎片导致频繁 Full GC。
  • 适用场景
    • 对响应时间敏感的应用(如 Web 服务器、电商系统)。
    • 堆内存中等大小(通常小于 16GB),且 CPU 核心数充足。
  • 注意:JDK 9 中被标记为 deprecated,JDK 14 中移除,推荐用 G1 替代。
  • 启用参数-XX:+UseConcMarkSweepGC

4. G1(Garbage-First)

  • 特点
    • 面向大堆内存(支持数十 GB 甚至更大),兼顾吞吐量和延迟。
    • 将堆内存划分为多个大小相等的 Region(区域),优先回收垃圾最多的 Region("Garbage-First")。
    • 采用"标记-复制"(Region 间复制)和"标记-整理"算法,减少内存碎片。
    • STW 停顿可预测,支持设置最大停顿时间目标(-XX:MaxGCPauseMillis)。
    • 同时管理新生代和老年代,无需配合其他收集器。
  • 适用场景
    • 大堆内存应用(如大型分布式系统、中间件)。
    • 既要求一定吞吐量,又需要控制延迟的场景(如企业级应用)。
    • 替代 CMS 的主流选择(JDK 9 后默认 GC)。
  • 启用参数-XX:+UseG1GC(JDK 9+ 默认)

5. ZGC(Z Garbage Collector)

  • 特点
    • 超低延迟设计,STW 时间控制在毫秒级以内(通常 < 10ms),且几乎不随堆大小增长而增加。
    • 支持超大堆内存(TB 级),采用基于 Region 的内存布局。
    • 并发执行大部分回收阶段(标记、转移、重定位),仅初始标记和最终标记有极短 STW。
    • 采用"标记-复制"算法,通过着色指针和读屏障实现高效并发操作。
    • 缺点:吞吐量略低于 G1,内存开销较高(额外占用约 15-30% 堆空间)。
  • 适用场景
    • 超大堆内存应用(如大型数据库、大数据处理)。
    • 对延迟极端敏感的场景(如高频交易、实时响应系统)。
  • 启用参数-XX:+UseZGC(JDK 11 引入,JDK 15 正式可用)

6. Shenandoah

  • 特点
    • 目标是低延迟,STW 时间与堆大小无关(支持 GB 到 TB 级堆)。
    • 采用"标记-整理"算法,通过转发指针和读屏障实现并发压缩(无内存碎片)。
    • 所有阶段(除初始标记和最终标记)均并发执行,STW 时间极短(通常 < 10ms)。
    • 与 ZGC 相比,内存开销较低,但实现更复杂。
  • 适用场景
    • 大堆内存且对延迟敏感的应用(如分布式服务、实时数据分析)。
    • 需要平衡延迟和内存开销的场景。
  • 注意:Oracle JDK 不包含 Shenandoah,主要在 OpenJDK、RedHat 等发行版中提供。
  • 启用参数-XX:+UseShenandoahGC(JDK 12 引入)

总结对比

收集器 延迟特性 吞吐量 堆大小支持 适用场景 典型应用示例
Serial GC 高延迟(STW长) 小(<1GB) 客户端/嵌入式 桌面应用、小程序
Parallel GC 中延迟 中(<10GB) 吞吐量优先的批处理任务 数据分析、后台计算
CMS 低延迟(部分阶段并发) 中(<16GB) 响应时间敏感的中小堆应用 传统 Web 服务
G1 可预测延迟 中高 大(<100GB) 平衡延迟与吞吐量的大堆应用 企业级应用、中间件
ZGC 超低延迟 超大(TB级) 超大堆+极端低延迟需求 高频交易、大型数据库
Shenandoah 超低延迟 超大(TB级) 超大堆+平衡内存开销 分布式服务、实时数据处理

选择时需根据应用的延迟需求、堆大小、CPU 资源等因素综合考量,优先推荐 G1(通用场景)、ZGC/Shenandoah(超大堆+低延迟)。