垃圾收集器发展历程

时间线

年份收集器特点适用场景
1999Serial单线程客户端
2002Parallel并行,高吞吐量服务端
2004CMS并发,低延迟互联网应用
2012G1分区,可预测停顿大内存应用
2018ZGC/Shenandoah超低延迟大内存、低延迟要求

核心概念

并行(Parallel)vs 并发(Concurrent)

并行(Parallel)

  • 多个GC线程同时工作
  • 仍需Stop The World
  • 缩短停顿时间
应用线程: ████████ [暂停] ████████
GC线程1:          ▓▓▓▓▓
GC线程2:          ▓▓▓▓▓
GC线程3:          ▓▓▓▓▓

并发(Concurrent)

  • GC线程与应用线程同时运行
  • 减少Stop The World时间
  • 实现更复杂
应用线程: ████████████████████████
GC线程:   ░░░░░░░░░░░░░░░░░░░░░░░░
         (大部分时间并发执行)

吞吐量 vs 低延迟

吞吐量优先(Throughput)

  • 关注总体执行效率
  • 适合后台计算、批处理
  • 代表:Parallel Scavenge

低延迟优先(Low Latency)

  • 关注单次停顿时间
  • 适合Web应用、交互式应用
  • 代表:CMS、G1、ZGC

权衡

吞吐量 = 运行用户代码时间 / (运行用户代码时间 + GC时间)

例如:
· 100秒运行时间,GC耗时5秒 → 吞吐量 = 95%
· 低延迟可能牺牲吞吐量

收集器组合

经典组合(JDK 8)

新生代收集器              老年代收集器
┌─────────────┐         ┌──────────────┐
│   Serial    │────────▶│  Serial Old  │
└─────────────┘         └──────────────┘
      ↓
┌─────────────┐         ┌──────────────┐
│   ParNew    │────────▶│     CMS      │
└─────────────┘         └──────────────┘
      ↓
┌─────────────┐         ┌──────────────┐
│  Parallel   │────────▶│ Parallel Old │
│  Scavenge   │         └──────────────┘
└─────────────┘

┌────────────────────────────────────┐
│           G1收集器                  │
│  (统一收集新生代和老年代)            │
└────────────────────────────────────┘

┌────────────────────────────────────┐
│      ZGC / Shenandoah              │
│  (低延迟收集器)                     │
└────────────────────────────────────┘

收集器对比

收集器类型算法停顿时间吞吐量适用场景
Serial新生代复制客户端
ParNew新生代复制配合CMS
Parallel Scavenge新生代复制后台计算
Serial Old老年代标记-整理客户端
Parallel Old老年代标记-整理后台计算
CMS老年代标记-清除Web应用
G1全堆标记-整理 + 复制可控大内存应用
ZGC全堆着色指针极短超大堆
Shenandoah全堆转发指针极短超大堆

选择建议

应用类型与收集器

1. 单CPU、小内存(<100MB)

-XX:+UseSerialGC

2. 多CPU、中等内存、吞吐量优先

-XX:+UseParallelGC

3. 多CPU、大内存、低延迟要求

# JDK 8
-XX:+UseConcMarkSweepGC

# JDK 9+
-XX:+UseG1GC  # (默认)

4. 超大堆(>4GB)、极低延迟

# JDK 11+
-XX:+UseZGC

# JDK 12+
-XX:+UseShenandoahGC

总结

核心要点

  1. 并行:多线程GC,仍需STW;并发:GC与应用同时运行
  2. 吞吐量优先:Parallel;低延迟优先:CMS/G1/ZGC
  3. 发展趋势:单线程 → 并行 → 并发 → 低延迟
  4. 选择原则:根据应用特点、内存大小、延迟要求选择

参考资料


下一篇预告:《Serial/Serial Old:单线程收集器》