Skip to content

Parallel/Parallel Old 回收器

高吞吐量的代表

Parallel GC(Throughput GC)是 JVM 中吞吐量最高的收集器组合:年轻代用 Parallel Scavenge,老年代用 Parallel Old。它专门为高吞吐量场景设计,适合批处理和离线计算。

Parallel Scavenge vs ParNew

很多人把 Parallel Scavenge 和 ParNew 混淆——它们确实非常相似(都是多线程年轻代收集器,都用复制算法),但关键区别在于优化目标不同

维度Parallel ScavengeParNew
设计目标高吞吐量尽量缩短停顿时间
自适应调节支持(自动调节 Survivor、晋升阈值)不支持
可组合Parallel Old(Throughput 组合)CMS
吞吐量更高(专门优化)较低
停顿时间较长较短

Parallel GC 的工作原理

年轻代:Parallel Scavenge(吞吐量优先的复制算法)

年轻代收集(Parallel Scavenge):
┌──────────────────────────────────────────────┐
│                                              │
│   线程1 ──▶ Eden 区域1                      │
│   线程2 ──▶ Eden 区域2                      │
│   线程3 ──▶ Eden 区域3                      │
│   线程4 ──▶ Eden 区域4                      │
│                                              │
│   N 个线程并行扫描、复制存活对象              │
│                                              │
│   吞吐量目标:吞吐量优先,而非最短停顿        │
│                                              │
└──────────────────────────────────────────────┘

老年代:Parallel Old(吞吐量优先的标记-压缩)

老年代收集(Parallel Old):
┌──────────────────────────────────────────────┐
│                                              │
│   线程1 ──▶ 老年代区域1 ──▶ 标记            │
│   线程2 ──▶ 老年代区域2 ──▶ 标记            │
│   线程3 ──▶ 老年代区域3 ──▶ 标记            │
│   线程4 ──▶ 老年代区域4 ──▶ 标记            │
│                                              │
│   N 个线程并行标记、压缩                     │
│                                              │
└──────────────────────────────────────────────┘

Parallel GC 的使用

bash
# 启用 Throughput GC(Parallel Scavenge + Parallel Old)
java -XX:+UseParallelGC MyApp

# 等价于(显式指定):
java -XX:+UseParallelGC -XX:+UseParallelOldGC MyApp

核心参数

吞吐量控制

bash
# 设置目标吞吐量(GC 时间 / 总时间)
# -XX:GCTimeRatio=N:GC 时间占总时间不超过 1/(N+1)
# 默认 GCTimeRatio=19 → GC 时间 ≤ 5%
java -XX:GCTimeRatio=19 MyApp  # 目标吞吐量 95%

# 例子:
# GCTimeRatio=9 → 目标吞吐量 90%(GC ≤ 10%)
# GCTimeRatio=99 → 目标吞吐量 99%(GC ≤ 1%)

停顿时间控制

bash
# 设置最大停顿时间目标(软目标,不是硬限制)
java -XX:MaxGCPauseMillis=200 MyApp
# 目标:GC 停顿不超过 200ms
# JVM 会自动调整堆大小和 GC 策略来满足这个目标

自适应调节

bash
# 启用自适应调节(默认开启)
java -XX:+UseAdaptiveSizePolicy MyApp

# 自适应调节会自动调整:
# - Survivor 比例
# - 晋升阈值
# - 年轻代大小
# 目的是在满足吞吐量和停顿时间目标的前提下,
# 尽量优化内存使用

并行线程数

bash
# 设置 GC 并行线程数
java -XX:ParallelGCThreads=8 MyApp

# 默认值 = CPU 核心数
# 建议:如果机器有超线程,设置为核心数的一半或相等

Parallel GC 的 GC 日志

bash
java -XX:+UseParallelGC \
     -XX:+PrintGCDetails \
     -XX:+PrintGCDateStamps \
     -XX:+PrintGCTimeStamps \
     MyApp

日志示例:

# 年轻代收集(Parallel Scavenge)
2026-03-22T10:00:00.123: [GC
  [PSYoungGen: 1024000K->204800K(1187840K)]
  1024000K->204800K(2097152K), 0.0456789 secs]
  [Times: user=0.18 sys=0.01, real=0.05 secs]
#                    ↑
#               user 时间(多线程累加)> real 时间

# 老年代收集(Parallel Old)
2026-03-22T10:00:30.456: [Full GC
  [PSYoungGen: 204800K->0K(1187840K)]
  [ParOldGen: 1572864K->1048576K(1572864K)]
  1777664K->1048576K(2760704K), 1.2345678 secs]
  [Times: user=4.92 sys=0.08, real=1.23 secs]

Parallel GC 的特点

吞吐量优先的设计

吞吐量 = 应用运行时间 / (应用运行时间 + GC 时间)

Parallel GC 的优化方向:
  → 最大化吞吐量
  → 但允许较长的单次停顿

Throughput vs 停顿时间权衡:
┌─────────────────────────────────────────────┐
│                                             │
│   Parallel GC ──▶ 高吞吐量 ──▶ 长停顿     │
│                                             │
│   G1 ──────────▶ 平衡 ──────────▶ 中停顿   │
│                                             │
│   ZGC ─────────▶ 低延迟 ─────────▶ 短停顿  │
│                                             │
└─────────────────────────────────────────────┘

自适应调节详解

当开启 -XX:+UseAdaptiveSizePolicy 时,JVM 会自动调整:

参数自动调节说明
SurvivorRatio自动调整Eden:Survivor 比例
MaxTenuringThreshold自动调整晋升老年代的年龄阈值
年轻代大小自动调整根据停顿时间目标调整
bash
# 示例:设置吞吐量目标,让 JVM 自动调优
java -XX:+UseParallelGC \
     -XX:GCTimeRatio=19 \       # 目标吞吐量 95%
     -XX:MaxGCPauseMillis=500 \ # 目标最大停顿 500ms
     -XX:+UseAdaptiveSizePolicy \
     MyApp

Parallel GC vs 其他收集器

维度Parallel GCG1ZGC
吞吐量⭐⭐⭐⭐⭐ 最高⭐⭐⭐ 中⭐⭐ 低
停顿时间⭐ 长⭐⭐ 可预测⭐⭐⭐⭐ 亚毫秒
堆大小影响堆越大停顿越长可控几乎不受影响
适合场景批处理、离线计算Web 服务低延迟场景
JDK 版本1.4+7+(JDK 9 默认)11+

本节小结

Parallel GC 的核心要点:

维度Parallel ScavengeParallel Old
管理区域年轻代老年代
算法复制标记-压缩
线程数多线程并行多线程并行
设计目标高吞吐量高吞吐量
自适应调节支持支持

Parallel GC 适合那些吞吐量优先、对停顿时间不敏感的场景——批处理作业、数据分析、科学计算等。

下一节,我们来看 CMS 回收器(原理/特点/参数/弊端)

基于 VitePress 构建