---
title: JVM GC 器选型与调优
type: concept
domain: java-concurrency
tags: [jvm, gc, serialgc, parnew, parallel, cms, g1, zgc, shenandoah, tuning]
status: learning
created: 2026-09-22
last_reviewed: 2026-09-22
method: feynman
related_questions:
  - "项目中如何选择垃圾回收器？为啥选择这个？"
related_knowledge:
  - ./jvm-gc-algorithms.md
  - ./jvm-gc-concurrent.md
  - ./jvm-oom.md
anki_cards: 5
interview_rounds:
  - "2026-09-22-round-1-Q10"
---

# JVM GC 器选型与调优

> GC 器选型 = 吞吐 vs 停顿 vs 空间的权衡三角。用**三层漏斗**决策：**JDK 版本 → 内存规模 → 业务特征**。G1 是绝大多数 Web 服务的默认答案。

## TL;DR（30 秒扫完）

- 演进：Serial → Parallel → CMS → G1 → ZGC/Shenandoah
- 权衡三角：**吞吐 vs 停顿 vs 空间**，不可兼得
- 三层漏斗：**JDK 版本**（硬约束）→ **内存规模**（G1 4-32GB 最佳）→ **业务特征**（吞吐/延迟/空间优先）
- G1 核心优势：Region 结构 + 可预测停顿 + Mixed GC 避免退化 Full GC
- ZGC 核心：读屏障+多映射，STW <1ms，堆 8MB-16TB

## 关键结论

- **结论 A**：GC 器没有最好的，只有最适合的——按 JDK 版本定范围，按内存规模定候选，按业务特征定取舍
- **结论 B**：**G1 是 JDK 9+ 默认**，4-32GB 堆最佳，Web 服务通用推荐
- **结论 C**：**ZGC JDK 15 GA**，堆 4GB+，STW <10ms，JDK 21 引入分代 ZGC
- **结论 D**：核心调优参数 `-Xms=-Xmx` 避免动态扩缩
- **结论 E**：评估靠 GC 日志+JFR，关注 GC 频率、STW P99、FullGC 次数、堆使用率

## 完整讲解（费曼四步）

### STEP 1 · 概念

GC 器选型本质是在**吞吐 vs 停顿 vs 空间**的权衡三角里做取舍。JDK 版本决定可用 GC 器范围，内存规模决定候选，业务特征决定取舍。

### STEP 2 · 大白话

> **类比**：GC 器选型像买车。
> - **JDK 版本**：决定你有哪些车型可选（老车买不到新车款）
> - **内存规模**：堆 1GB 用 Serial（小车），16GB 用 G1（家用车），64GB+ 用 ZGC（大车）
> - **业务特征**：批量运输用 ParallelGC（载重），市内通勤用 G1（舒适），长途高速用 ZGC（低延迟）
> 
> **没有最好的车，只有最适合你行程的车。**

### STEP 3 · 底层

#### GC 器演进主线

| GC 器 | 引入版本 | 特点 | 现状 |
|-------|---------|------|------|
| Serial | JDK 1.2 | 单线程，为快而生 | 小堆单核（<1GB） |
| ParallelGC | JDK 5 | 并行化，求吞吐 | JDK 8 默认 |
| CMS | JDK 5 | 并发标记-清除，求停顿 | **JDK 14 弃用移除** |
| G1 | JDK 7 | Region+可预测停顿 | **JDK 9+ 默认** |
| ZGC | JDK 15 GA | 读屏障+多映射，STW <1ms | TB 级堆首选 |
| Shenandoah | JDK 11 | 写屏障+Brooks 转发，STW <10ms | RedHat 主推 |

#### 三层漏斗决策

**第一层：JDK 版本**（硬约束）
- JDK 8 用不了 ZGC（ZGC JDK 15 GA）
- JDK 14 之后 CMS 被移除
- JDK 9+ 默认 G1
- JDK 21 引入分代 ZGC

**第二层：内存规模**
- Serial：<1GB
- G1：**4-32GB 最佳**
- ZGC：4GB+，可到 16TB
- Shenandoah：32GB+

**第三层：业务特征**
- 批处理/后台任务 → ParallelGC（吞吐优先）
- Web 服务通用 → G1（推荐）
- 低延迟+大堆 → ZGC
- 需要并发优先 → Shenandoah

#### GC 器对比表

| GC 器 | 吞吐 | 停顿 | 空间 | 堆规模 | 推荐场景 |
|------|------|------|------|--------|---------|
| Serial | 低 | 长 | 高 | <1GB | 嵌入式、单核 |
| ParallelGC | 高 | 中 | 中 | 4-32GB | 批处理、后台任务 |
| CMS | 中 | 短（但有碎片） | 中 | 已弃用 | JDK 14 移除 |
| G1 | 中 | 可预测 | 中 | 4-32GB | Web 服务通用 |
| ZGC | 中 | 极短 <10ms | 中 | 4GB-16TB | 大堆、低延迟 |
| Shenandoah | 中 | 短 <10ms | 中 | 32GB+ | 并发优先 |

#### G1 的核心优势

1. **Region 结构**：堆切成等大 Region（1MB-32MB），回收选最脏的 Region 优先，避免整堆扫描
2. **可预测停顿**：`-XX:MaxGCPauseMillis` 目标停顿，G1 自动决定每次回收多少 Region
3. **Mixed GC**：Young + 部分老年代 Region，避免退化到 Full GC
4. **无碎片**：Region 内可整理

#### ZGC 的核心优势

1. **读屏障+多映射**：STW 只有 Initial Mark 和 Final Relocate 两瞬间，都 <1ms
2. **堆 8MB-16TB**：大堆首选
3. **堆外内存感知**：JDK 21+ 可管理 DirectByteBuffer 生命周期
4. JDK 21 引入**分代 ZGC**（Young/Old 分区）

#### 实战调优参数

**G1 关键参数**：
```bash
-XX:+UseG1GC                          # 启用 G1
-XX:MaxGCPauseMillis=200               # 目标停顿（默认 200ms）
-XX:G1HeapRegionSize=16m               # Region 大小（默认动态）
-XX:InitiatingHeapOccupancyPercent=45  # 并发标记启动阈值（默认 45%）
-Xms4g -Xmx4g                         # 堆大小（建议相等）
```

**ZGC 关键参数**：
```bash
-XX:+UseZGC                            # 启用 ZGC
-Xms4g -Xmx4g                         # 堆大小（建议相等）
```

**通用必备**：
```bash
-Xms=Xmx                                # 避免动态扩缩开销
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:MaxDirectMemorySize=512m            # 堆外内存上限
-XX:+HeapDumpOnOutOfMemoryError         # 救命参数
-Xlog:gc*                               # GC 日志（JDK 9+）
```

#### GC 评估手段

**GC 日志**：
- JDK 9+：`-Xlog:gc*`
- JDK 8：`-XX:+PrintGCDetails -XX:+PrintGCTimeStamps`

**JFR 事件**：
- `jdk.GCPhasePause`：GC 各阶段耗时
- `jdk.GCHeapSummary`：堆使用汇总
- `jdk.GCObjectAllocationInNewTLAB`：TLAB 分配
- `jdk.Safepoint`：安全点事件

**生产监控**：
- Prometheus + JVMExporter
- Grafana 大盘

**关键指标**：
- GC 频率（每秒数次 YoungGC 正常，FullGC 应极少）
- **STW P99**（生产要求 <200ms）
- FullGC 次数
- 堆使用率（FullGC 后仍 >70% 说明有泄漏）
- Metaspace 使用率

#### 场景选型参考

| 场景 | 堆大小 | JDK 版本 | 推荐 GC |
|------|-------|---------|---------|
| 嵌入式/单核 | <1GB | 任意 | Serial |
| 批处理/后台 | 4-32GB | JDK 8+ | ParallelGC |
| Web 服务通用 | 4-32GB | JDK 8+ | G1（推荐） |
| Web 服务低延迟 | 4-32GB | JDK 15+ | ZGC |
| 大堆服务 | 32GB-16TB | JDK 15+ | ZGC |
| 需要并发优先 | 32GB+ | JDK 11+ | Shenandoah |

#### JDK 8 → JDK 17 升级注意点

1. **CMS 已弃用**（JDK 14 移除），必须换 G1/ZGC
2. **模块系统**（JPMS）
3. **Finalization 弃用**改 Cleaner
4. **`-Xlog`** 替代 `-XX:+Print*`
5. **JFR** 事件更丰富

### STEP 4 · 简化

> **一句话总结**：GC 器没有最好的，只有最适合的——三层漏斗决策，G1 是通用答案，ZGC 是大堆进阶。

**记忆口诀**：
- **三层漏斗**：JDK → 内存规模 → 业务特征
- **G1 三优势**：Region / 可预测 / Mixed
- **ZGC 二件套**：读屏障 + 多映射
- **评估三指标**：GC 频率 / STW P99 / FullGC 次数

## 常见误区

- **误区 1**："CMS 还是可用的" → 正确：JDK 14 已移除，JDK 17/21 用不了
- **误区 2**："G1 可以支持任意堆大小" → 正确：G1 在 4-32GB 最佳，超过 32GB 停顿开始退化
- **误区 3**："ZGC 需要大堆才用" → 正确：ZGC 从 4GB 起也能跑，JDK 21 分代 ZGC 更优
- **误区 4**："`-Xms` 和 `-Xmx` 分开设没问题" → 正确：**建议相等**避免动态扩缩开销
- **误区 5**："G1 停顿时间固定" → 正确：G1 是**可预测停顿**（`-XX:MaxGCPauseMillis` 是目标），实际由 Region 大小决定

## 延伸追问

1. **G1 的 Region 和传统分代区别？**
   - G1 是**逻辑分代**（Region 标记为 Young/Old/Humongous），不是物理分代；回收选任意 Region，避免整堆扫描
2. **ZGC 如何实现 <10ms 停顿？**
   - 并发标记+并发整理+读屏障+多映射；移动对象时改映射而非改引用；STW 只有 Initial Mark 和 Final Relocate 两瞬间
3. **如何在生产上评估 GC 是否合适？**
   - GC 日志 `-Xlog:gc*`、JFR `jdk.GCPhasePause`、Prometheus + JVMExporter；关键指标：GC 频率、STW P99、FullGC 次数、堆使用率
4. **JDK 8 升级到 JDK 17 要注意什么？**
   - CMS 已弃用（JDK 14 移除）必须换 G1/ZGC；模块系统（JPMS）；Finalization 弃用改 Cleaner；`-Xlog` 替代 `-XX:+Print*`；JFR 事件更多
5. **什么时候从 G1 换 ZGC？**
   - 堆 >32GB、P99 STW 敏感（如支付/实时交易）、JDK 15+、可接受略低吞吐；换 ZGC 前要压测对比吞吐和延迟

## 速查表

```
GC 演进: Serial → Parallel → CMS(弃用) → G1 → ZGC/Shenandoah

三层漏斗:
  1. JDK 版本 (硬约束)
  2. 内存规模 (4-32GB 用 G1, >32GB 用 ZGC)
  3. 业务特征 (吞吐/延迟/空间)

场景选型:
  <1GB → Serial
  4-32GB Web → G1
  >32GB 低延迟 → ZGC
  批处理 → ParallelGC

关键参数:
  G1: -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45
  ZGC: -XX:+UseZGC
  通用: -Xms=Xmx (避免扩缩)

评估指标:
  GC 频率 / STW P99 / FullGC 次数 / 堆使用率
```

## 关联题目（题库）

- 《项目中如何选择垃圾回收器？为啥选择这个？》— Round 1 Q10, ⭐⭐⭐⭐（本轮最佳）

## 关联知识

- [JVM GC 算法与 STW](./jvm-gc-algorithms.md)
- [JVM GC 并发机制与三色标记](./jvm-gc-concurrent.md)
- [JVM OOM 完整分类与排查](./jvm-oom.md)
- [主题地图](./_moc.md)

## Anki 候选卡片

1. **正**：GC 器演进主线？**反**：Serial → Parallel → CMS（弃用）→ G1 → ZGC/Shenandoah
2. **正**：G1 三大优势？**反**：Region 结构 / 可预测停顿 / Mixed GC
3. **正**：ZGC 核心技术？**反**：读屏障 + 多映射，STW <1ms
4. **正**：G1 关键调优参数？**反**：`-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45`
5. **正**：JDK 8 升级到 JDK 17 最需注意？**反**：CMS 已弃用（JDK 14 移除），必须换 G1/ZGC

---

*最后更新：2026-09-22*
