JVM 垃圾收集器(GC)完全指南

涵盖 Serial、Parallel、CMS、G1、ZGC、Shenandoah 六大垃圾收集器


目录

  1. JVM 堆内存基础结构
  2. Serial GC(串行收集器)
  3. Parallel GC(并行收集器)
  4. CMS GC(并发标记清除)
  5. G1 GC(Garbage First)
  6. ZGC(Z Garbage Collector)
  7. Shenandoah GC
  8. GC 对比总结
  9. GC 调优实战

一、JVM 堆内存基础结构

在了解各 GC 之前,先理解通用的堆内存结构:

┌─────────────────────────────────────────────────────────────┐
│                        JVM Heap                             │
├─────────────────────┬───────────────────────────────────────┤
│     Young Generation │         Old Generation (Tenured)      │
│    (新生代 ~1/3)     │           (老年代 ~2/3)               │
├──────────┬──────────┤                                       │
│   Eden   │ Survivor │                                       │
│  (~8/10) │ S0 + S1 │                                       │
│          │ (各1/10) │                                       │
└──────────┴──────────┴───────────────────────────────────────┘

对象晋升流程:
Eden → Survivor(S0↔S1) → Old Generation

分代假设

  1. 弱分代假说:绝大多数对象都是朝生夕灭的
  2. 强分代假说:熬过越多次垃圾收集的对象越难以消亡

二、Serial GC(串行收集器)

内存结构

┌────────────────────────────────────────┐
│              Single Thread             │
│  ┌──────────────────────────────────┐  │
│  │         Young Generation         │  │
│  │  ┌───────┬────┬────┐            │  │
│  │  │ Eden  │ S0 │ S1 │            │  │
│  │  └───────┴────┴────┘            │  │
│  └──────────────────────────────────┘  │
│  ┌──────────────────────────────────┐  │
│  │          Old Generation          │  │
│  │                                  │  │
│  └──────────────────────────────────┘  │
└────────────────────────────────────────┘

执行原理

阶段 操作 说明
新生代 GC 复制算法 单线程复制存活对象到 Survivor/Old
老年代 GC 标记-整理算法 标记存活 → 整理消除碎片
执行流程(STW):
1. 暂停所有应用线程
2. 新生代:Eden + From Survivor → To Survivor
3. 老年代:标记存活对象 → 整理内存
4. 恢复应用线程

优缺点

优点 缺点
简单高效(单核) 单线程,多核利用率低
内存占用小 STW 时间长
适合客户端应用 不适合服务端

优化参数

# 启用参数
-XX:+UseSerialGC

# 调整新生代大小
-XX:NewRatio=2          # Old:New = 2:1
-XX:SurvivorRatio=8     # Eden:S0:S1 = 8:1:1

# 晋升阈值
-XX:MaxTenuringThreshold=15

适用场景

  • 单核机器
  • 小内存应用(< 100MB)
  • 客户端应用

三、Parallel GC(并行收集器 / Throughput Collector)

内存结构

┌────────────────────────────────────────┐
│           Multiple Threads             │
│  ┌──────────────────────────────────┐  │
│  │         Young Generation         │  │
│  │  ┌───────┬────┬────┐            │  │
│  │  │ Eden  │ S0 │ S1 │ ← 多线程复制│  │
│  │  └───────┴────┴────┘            │  │
│  └──────────────────────────────────┘  │
│  ┌──────────────────────────────────┐  │
│  │          Old Generation          │  │
│  │                    ← 多线程整理   │  │
│  └──────────────────────────────────┘  │
└────────────────────────────────────────┘

执行原理

Parallel Scavenge(新生代):
┌─────────────────────────────────────────┐
│ Thread1: Eden区扫描 → 复制存活对象      │
│ Thread2: Eden区扫描 → 复制存活对象      │
│ Thread3: Eden区扫描 → 复制存活对象      │
│ Thread4: Survivor扫描 → 复制存活对象    │
│ ...                                     │
└─────────────────────────────────────────┘

Parallel Old(老年代):
多线程执行标记-整理算法

核心特点

特性 说明
关注吞吐量 CPU 运行用户代码时间 / 总时间
自适应调节 可自动调整新生代大小
并行执行 多线程垃圾收集

优化参数

# 启用参数
-XX:+UseParallelGC           # JDK 8 默认
-XX:+UseParallelOldGC        # 老年代并行(默认开启)

# 吞吐量目标
-XX:GCTimeRatio=99           # GC时间占比目标 1/(1+99)=1%
-XX:MaxGCPauseMillis=200     # 最大停顿时间目标

# 并行线程数
-XX:ParallelGCThreads=N      # 默认 = CPU核心数

# 自适应策略
-XX:+UseAdaptiveSizePolicy   # 开启自适应(默认开启)

# 新生代调优
-XX:NewSize=256m
-XX:MaxNewSize=256m

适用场景

  • 后台计算任务
  • 批处理系统
  • 科学计算
  • 不需要交互的应用

四、CMS GC(并发标记清除)

内存结构

┌────────────────────────────────────────┐
│                                        │
│  ┌──────────────────────────────────┐  │
│  │         Young Generation         │  │
│  │  ┌───────┬────┬────┐            │  │
│  │  │ Eden  │ S0 │ S1 │            │  │
│  │  └───────┴────┴────┘            │  │
│  └──────────────────────────────────┘  │
│  ┌──────────────────────────────────┐  │
│  │          Old Generation          │  │
│  │    ┌─────────────────────────┐   │  │
│  │    │ 可能有内存碎片(不整理) │   │  │
│  │    └─────────────────────────┘   │  │
│  └──────────────────────────────────┘  │
└────────────────────────────────────────┘

执行原理(4个阶段)

┌─────────────────────────────────────────────────────────────┐
│                    CMS 老年代收集流程                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Initial Mark(初始标记)- STW                           │
│     └─ 标记 GC Roots 直接关联的对象                         │
│        速度很快,停顿短                                      │
│                                                             │
│  2. Concurrent Mark(并发标记)                             │
│     └─ 从 GC Roots 遍历整个对象图                           │
│        与用户线程并发执行                                    │
│                                                             │
│  3. Remark(重新标记)- STW                                 │
│     └─ 修正并发标记期间变动的对象                            │
│        使用增量更新                          │
│                                                             │
│  4. Concurrent Sweep(并发清除)                            │
│     └─ 清除标记为死亡的对象                                  │
│        与用户线程并发执行                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

三色标记算法

┌────────────────────────────────────────┐
│            三色标记法                  │
├────────────────────────────────────────┤
│  ⚪ 白色:未被访问,可能是垃圾          │
│  ⚫ 黑色:已访问,存活对象              │
│  🔘 灰色:已访问,但引用未扫描完        │
├────────────────────────────────────────┤
│  扫描流程:                            │
│  白色 → 灰色 → 黑色                    │
│  最终白色对象即为垃圾                  │
└────────────────────────────────────────┘

CMS 的对象消失问题

问题场景(并发标记期间):
1. 黑色对象新增了对白色对象的引用
2. 灰色对象删除了对白色对象的引用
→ 白色对象被错误回收!

CMS 解决方案:增量更新
- 记录新增的引用关系
- 重新标记阶段重新扫描

优缺点

优点 缺点
低延迟 内存碎片问题
并发收集 CPU 敏感
适合互联网应用 浮动垃圾
JDK 9 标记废弃,JDK 14 移除

优化参数

# 启用参数
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC            # 新生代使用 ParNew(默认)

# 并发线程数
-XX:ConcGCThreads=N         # 默认 = (ParallelGCThreads + 3) / 4

# 内存碎片
-XX:CMSFullGCsBeforeCompaction=0  # 每次 Full GC 都整理
-XX:+UseCMSCompactAtFullCollection

# 浮动垃圾
-XX:CMSInitiatingOccupancyFraction=75  # 老年代75%时触发
-XX:+UseCMSInitiatingOccupancyOnly

# 增量模式(单核CPU)
-XX:+CMSIncrementalMode

# 并发标记优化
-XX:+CMSParallelRemarkEnabled
-XX:+CMSScavengeBeforeRemark

适用场景

  • 互联网网站
  • B/S 架构服务端
  • 要求低延迟的应用
  • JDK 8 及以下版本

五、G1 GC(Garbage First)

内存结构(Region 化)

┌─────────────────────────────────────────────────────────────┐
│                       G1 Heap                               │
│  ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐  │
│  │ E  │ E  │ S  │ S  │ O  │ O  │ O  │ O  │ H  │ H  │ E  │  │
│  └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘  │
│   ↑              ↑              ↑       ↑                   │
│  Eden         Survivor        Old    Humongous              │
│                                                        │
│  Region 大小:1MB ~ 32MB(2的幂次)                     │
│  默认约 2048 个 Region                                  │
└─────────────────────────────────────────────────────────────┘

图例:
E = Eden Region
S = Survivor Region  
O = Old Region
H = Humongous Region(大对象,> Region 50%)

执行原理

┌─────────────────────────────────────────────────────────────┐
│                    G1 收集模式                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  【Young GC】                                               │
│   └─ 回收所有 Eden + Survivor Region                        │
│      复制存活对象到新 Survivor / Old                        │
│                                                             │
│  【并发标记周期】                                            │
│   1. Initial Mark(初始标记)- STW,伴随 Young GC           │
│   2. Root Region Scan(根区域扫描)- 并发                   │
│   3. Concurrent Mark(并发标记)- 并发                      │
│   4. Remark(最终标记)- STW                                │
│   5. Cleanup(清理)- STW                                   │
│                                                             │
│  【Mixed GC】                                               │
│   └─ 回收部分老年代 Region(根据回收价值排序)              │
│                                                             │
│  【Full GC】(退化)                                        │
│   └─ 当 Mixed GC 无法跟上分配速度时触发                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

RSet(Remembered Set)

┌────────────────────────────────────────┐
│              RSet 结构                 │
├────────────────────────────────────────┤
│  每个 Region 维护一个 RSet             │
│  记录"谁引用了我"                      │
│                                        │
│  作用:                                │
│  - 避免 Full Heap 扫描                 │
│  - 只扫描 RSet 即可知道跨代引用        │
│                                        │
│  实现:                                │
│  - PRT(Per Region Table)             │
│  - Card Table                          │
└────────────────────────────────────────┘

SATB(Snapshot-At-The-Beginning)

G1 使用 SATB 解决并发标记问题:

原理:
- 在标记开始时创建快照
- 记录标记过程中的所有变更
- 最终标记时处理变更

与 CMS 增量更新对比:
┌─────────────┬──────────────────────────┐
│    CMS      │           G1             │
├─────────────┼──────────────────────────┤
│ 增量更新    │ SATB                     │
│ 记录新增引用│ 记录删除引用             │
│ 重新扫描    │ 基于快照                 │
│ 精度更高    │ 效率更高                 │
└─────────────┴──────────────────────────┘

优缺点

优点 缺点
可预测停顿时间 内存占用更高
无内存碎片 小堆性能不如 CMS
Region 化管理 大对象处理有开销
并发标记

优化参数

# 启用参数(JDK 9+ 默认)
-XX:+UseG1GC

# 停顿时间目标
-XX:MaxGCPauseMillis=200    # 默认 200ms

# Region 大小
-XX:G1HeapRegionSize=4m     # 不建议手动设置

# 新生代比例
-XX:G1NewSizePercent=5      # 新生代最小占比
-XX:G1MaxNewSizePercent=60  # 新生代最大占比

# 并发标记阈值
-XX:InitiatingHeapOccupancyPercent=45  # 堆占用45%触发

# Mixed GC 参数
-XX:G1MixedGCCountTarget=8  # Mixed GC 次数目标
-XX:G1HeapWastePercent=5    # 允许浪费的堆比例

# 大对象
-XX:G1HeapRegionSize=32m    # 增大 Region 减少大对象

# 并发线程
-XX:ConcGCThreads=4
-XX:ParallelGCThreads=8

适用场景

  • JDK 9+ 默认 GC
  • 大堆内存(> 4GB)
  • 要求可预测停顿时间
  • 多核服务器

六、ZGC(Z Garbage Collector)

内存结构

┌─────────────────────────────────────────────────────────────┐
│                       ZGC Heap                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                   ZPages                             │  │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐               │  │
│  │  │Small 2MB│ │Medium 32MB│ │Large N×2MB│             │  │
│  │  └─────────┘ └─────────┘ └─────────┘               │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                             │
│  支持最大堆:16TB                                           │
│  停顿时间目标:< 10ms(实际 < 1ms)                         │
└─────────────────────────────────────────────────────────────┘

Page 类型:
- Small Page:2MB,存放小于 256KB 的对象
- Medium Page:32MB,存放 256KB ~ 4MB 的对象
- Large Page:N × 2MB,存放大于 4MB 的对象

核心技术

┌────────────────────────────────────────────────────────────┐
│                    ZGC 核心技术                             │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  1. 着色指针                    │
│     ┌─────────────────────────────────────┐               │
│     │  64位指针:                          │               │
│     │  [未使用 16位][颜色位 4位][对象地址 42位]│               │
│     │                    ↑                 │               │
│     │    Finalizable / Remapped /          │               │
│     │    Marked1 / Marked0                 │               │
│     └─────────────────────────────────────┘               │
│     颜色位标记对象状态,无需额外数据结构                    │
│                                                            │
│  2. 读屏障                         │
│     ┌─────────────────────────────────────┐               │
│     │  if (指针颜色 != 期望颜色) {         │               │
│     │      自愈处理;                       │               │
│     │  }                                  │               │
│     └─────────────────────────────────────┘               │
│     在读取引用时检查并修正,实现并发转移                    │
│                                                            │
│  3. 多重映射                    │
│     同一物理内存映射到多个虚拟地址                          │
│     解决颜色位切换问题                                      │
│                                                            │
└────────────────────────────────────────────────────────────┘

执行流程

┌─────────────────────────────────────────────────────────────┐
│                    ZGC 收集阶段                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 标记开始 - STW(< 1ms)                                │
│     └─ 标记 GC Roots 直接引用                              │
│                                                             │
│  2. 并发标记                                               │
│     └─ 遍历对象图,利用读屏障                              │
│                                                             │
│  3. 标记结束 - STW(< 1ms)                                │
│     └─ 处理少量遗漏                                        │
│                                                             │
│  4. 并发转移准备                                           │
│     └─ 分析需要转移的 Region                               │
│                                                             │
│  5. 转移开始 - STW(< 1ms)                                │
│     └─ 初始化转移                                          │
│                                                             │
│  6. 并发转移                                               │
│     └─ 转移存活对象,利用读屏障                            │
│                                                             │
│  总 STW 时间:< 10ms(通常 < 1ms)                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

优缺点

优点 缺点
极低延迟(< 10ms) JDK 15 前不支持压缩指针
支持超大堆(16TB) 内存占用较高
无碎片 吞吐量略低于 Parallel
并发转移 JDK 版本要求高

优化参数

# 启用参数
-XX:+UseZGC                    # JDK 15+ 生产可用

# 并发线程
-XX:ConcGCThreads=4

# 堆大小
-Xmx16g                        # ZGC 适合大堆

# JDK 21+ 分代 ZGC
-XX:+UseZGC -XX:+ZGenerational

# 启用压缩指针(JDK 15+)
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops

适用场景

  • 超大堆内存(TB 级别)
  • 要求极低延迟(< 10ms)
  • JDK 15+ 生产环境
  • 金融交易、实时系统

七、Shenandoah GC

内存结构

┌─────────────────────────────────────────────────────────────┐
│                   Shenandoah Heap                           │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              Regions (无分代)                        │  │
│  │  ┌────┬────┬────┬────┬────┬────┬────┬────┐         │  │
│  │  │ R  │ R  │ R  │ R  │ R  │ R  │ R  │ R  │         │  │
│  │  └────┴────┴────┴────┴────┴────┴────┴────┘         │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                             │
│  Region 大小:与 G1 类似                                    │
│  停顿时间目标:< 10ms                                       │
└─────────────────────────────────────────────────────────────┘

核心技术

┌────────────────────────────────────────────────────────────┐
│                 Shenandoah 核心技术                         │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  1. 转发表                    │
│     ┌─────────────────────────────────────┐               │
│     │  记录对象转移映射                    │               │
│     │  旧地址 → 新地址                     │               │
│     └─────────────────────────────────────┘               │
│                                                            │
│  2. Brooks 指针                    │
│     ┌─────────────────────────────────────┐               │
│     │  每个对象头增加转发指针              │               │
│     │  正常指向自己,转移后指向新位置      │               │
│     └─────────────────────────────────────┘               │
│                                                            │
│  3. 读/写屏障                                              │
│     ┌─────────────────────────────────────┐               │
│     │  读取时检查转发指针                  │               │
│     │  实现并发转移                        │               │
│     └─────────────────────────────────────┘               │
│                                                            │
└────────────────────────────────────────────────────────────┘

执行流程

┌─────────────────────────────────────────────────────────────┐
│                  Shenandoah 收集阶段                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Initial Mark - STW                                     │
│     └─ 标记 GC Roots                                       │
│                                                             │
│  2. Concurrent Marking                                     │
│     └─ 并发标记整个堆                                      │
│                                                             │
│  3. Final Mark - STW                                       │
│     └─ 完成标记,计算回收集合                              │
│                                                             │
│  4. Concurrent Evacuation                                  │
│     └─ 并发转移存活对象                                    │
│                                                             │
│  5. Init Update Refs - STW                                 │
│     └─ 初始化引用更新                                      │
│                                                             │
│  6. Concurrent Update References                           │
│     └─ 并发更新引用                                        │
│                                                             │
│  7. Final Update Refs - STW                                │
│     └─ 完成引用更新                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

ZGC vs Shenandoah 对比

特性 ZGC Shenandoah
实现方式 着色指针 + 读屏障 转发表 + Brooks 指针
内存开销 较低 较高(转发表)
JDK 支持 JDK 15+ 生产 JDK 12+ 生产
最大堆 16TB 无限制
OpenJDK Oracle 主导 Red Hat 主导
分代支持 JDK 21+ 支持 JDK 21+ 支持

优化参数

# 启用参数
-XX:+UseShenandoahGC

# 并发线程
-XX:ConcGCThreads=4

# 堆大小
-Xmx8g

# 停顿时间
-XX:ShenandoahGuaranteedGCInterval=60000

适用场景

  • 低延迟要求
  • JDK 12+ 环境
  • 大堆内存
  • 对 Oracle ZGC 有顾虑的场景

八、GC 对比总结

性能对比

┌──────────────────────────────────────────────────────────────┐
│                     GC 性能对比图                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  停顿时间                                                    │
│  ↑                                                           │
│  │ ████████████████████████ Serial GC                       │
│  │ ████████████████ Parallel GC                             │
│  │ ████████████ CMS                                         │
│  │ ████████ G1                                              │
│  │ ████ Shenandoah                                          │
│  │ ██ ZGC                                                   │
│  └─────────────────────────────────────────────────────────→ │
│                                                              │
│  吞吐量                                                      │
│  ↑                                                           │
│  │ ████████████████████████ Parallel GC                     │
│  │ ████████████████████ G1                                  │
│  │ ████████████████ ZGC                                     │
│  │ ████████████████ Shenandoah                              │
│  │ ████████████ CMS                                         │
│  │ ████████ Serial                                          │
│  └─────────────────────────────────────────────────────────→ │
│                                                              │
└──────────────────────────────────────────────────────────────┘

选择指南

┌─────────────────────────────────────────────────────────────┐
│                    GC 选择决策树                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  堆内存大小?                                               │
│  │                                                          │
│  ├─ < 100MB ───────────────────→ Serial GC                 │
│  │                                                          │
│  ├─ 100MB ~ 4GB ───────────────→ G1 GC / Parallel GC       │
│  │                                                          │
│  └─ > 4GB ─────────────────────→ G1 / ZGC / Shenandoah     │
│                                                             │
│  延迟要求?                                                 │
│  │                                                          │
│  ├─ 无要求(批处理)───────────→ Parallel GC               │
│  │                                                          │
│  ├─ < 200ms ───────────────────→ G1 GC                     │
│  │                                                          │
│  └─ < 10ms ────────────────────→ ZGC / Shenandoah          │
│                                                             │
│  JDK 版本?                                                 │
│  │                                                          │
│  ├─ JDK 8 ─────────────────────→ CMS / G1 / Parallel       │
│  │                                                          │
│  ├─ JDK 11 ────────────────────→ G1                        │
│  │                                                          │
│  └─ JDK 17+ ───────────────────→ G1 / ZGC                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

各 GC 适用场景汇总

GC JDK 版本 堆大小 延迟要求 典型场景
Serial 所有 < 100MB 无要求 客户端、小应用
Parallel JDK 8 默认 中等 无要求 批处理、计算任务
CMS JDK 8- 中等 中等 互联网服务(已废弃)
G1 JDK 9+ 默认 > 4GB < 200ms 服务端通用
ZGC JDK 15+ > 8GB < 10ms 金融、实时系统
Shenandoah JDK 12+ 大堆 < 10ms 低延迟服务

关键记忆点

GC 核心算法 核心特点 一句话总结
Serial 复制 + 标记整理 单线程、简单 小内存首选
Parallel 复制 + 标记整理 多线程、吞吐量优先 批处理首选
CMS 复制 + 标记清除 并发、低延迟 JDK 8 低延迟(已废弃)
G1 Region + 复制 可预测停顿、无碎片 JDK 9+ 默认,服务端通用
ZGC 着色指针 + 读屏障 极低延迟、大堆 JDK 15+ 低延迟首选
Shenandoah 转发表 + Brooks 指针 低延迟 ZGC 替代方案

九、GC 调优实战

通用调优步骤

1. 确定目标
   ├─ 吞吐量优先?→ Parallel GC
   ├─ 延迟优先?→ G1 / ZGC
   └─ 内存小?→ Serial GC

2. 监控分析
   ├─ GC 日志分析
   ├─ JMX 监控
   └─ 工具:GCViewer、GCEasy、JVisualVM

3. 调整参数
   ├─ 堆大小
   ├─ 新生代比例
   └─ GC 线程数

4. 验证效果
   ├─ 压力测试
   ├─ 对比调优前后
   └─ 持续监控

GC 日志配置

# JDK 8
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-Xloggc:/path/to/gc.log

# JDK 9+(统一日志格式)
-Xlog:gc*:file=/path/to/gc.log:time,level,tags

# 详细日志
-Xlog:gc*,gc+heap=debug:file=gc.log

# 打印 GC 原因
-Xlog:gc+cause:file=gc.log

常见问题排查

┌─────────────────────────────────────────────────────────────┐
│                    常见 GC 问题                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Full GC 频繁                                           │
│     原因:堆太小 / 内存泄漏 / 大对象                        │
│     解决:增大堆 / 排查泄漏 / 调整大对象阈值                │
│                                                             │
│  2. Young GC 频繁                                          │
│     原因:新生代太小 / 对象过早晋升                         │
│     解决:增大新生代 / 调整晋升阈值                         │
│                                                             │
│  3. GC 停顿时间长                                          │
│     原因:堆太大 / 使用了 Serial GC                         │
│     解决:换 G1/ZGC / 减小堆 / 增加并发线程                 │
│                                                             │
│  4. 内存碎片                                               │
│     原因:CMS 不整理 / 对象大小不均                         │
│     解决:换 G1 / 定期触发 Full GC 整理                     │
│                                                             │
│  5. Metaspace/PermGen 溢出                                 │
│     原因:类加载过多 / 动态代理                             │
│     解决:增大 Metaspace / 排查类加载器泄漏                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

学习建议

  1. 先理解基础:分代、GC Roots、三色标记
  2. 重点掌握 G1:当前主流,面试必问
  3. 了解 ZGC:未来趋势,大厂在用
  4. 实践调优:配置 GC 日志,分析实际问题
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐