Java GC 与 ZGC 全面解析
Java GC 与 ZGC 全面解析
Java 垃圾回收(GC)是 JVM 自动管理内存的核心机制,而 ZGC(Z Garbage Collector)是 OpenJDK 推出的一款低延迟、可扩展的新一代垃圾收集器。本文从基础 GC 概念切入,深入解析 ZGC 的设计、原理、特性及适用场景。
一、Java GC 基础
1. 核心目标
GC 的核心是自动回收不再被引用的对象内存,避免内存泄漏和手动内存管理的复杂性,核心原则:
识别「存活对象」和「垃圾对象」;
回收垃圾对象占用的内存并重新分配;
尽可能减少对应用线程的停顿(STW,Stop-The-World)。
2. 经典 GC 分类(按代际 / 特性)
| 收集器 | 适用代际 | 核心特点 | 典型停顿时间 | 适用场景 |
| Serial GC | 新生代 | 单线程、简单高效 | 百毫秒级 | 小内存、单核场景 |
| Parallel GC | 新生代 | 多线程、高吞吐量 | 几十毫秒级 | 后台计算、批处理 |
| CMS | 老年代 | 并发标记清除、低延迟 | 毫秒级(部分阶段) | 低延迟要求的服务 |
| G1 GC | 整堆 | 区域化、可预测停顿 | 几十毫秒级 | 中等延迟、大内存场景 |
| ZGC | 整堆 | 并发、低延迟、可扩展 | 亚毫秒级(<10ms) | 超大内存、超低延迟场景 |
3. 经典 GC 的痛点
Serial/Parallel GC:STW 时间随堆内存增大线性增加;
CMS:内存碎片严重、并发阶段占用 CPU、无法处理浮动垃圾;
G1:大堆(如百 GB 级)下仍有明显 STW,内存划分粒度有限。
二、ZGC 核心解析
ZGC 是 OpenJDK 11 引入的实验性特性(JDK 15 正式发布),专为超大堆(TB 级)、超低延迟设计,核心目标:STW 时间不超过 10ms,且停顿时间不随堆大小 / 存活对象数量增加而增加。
1. ZGC 核心设计理念
(1)基于「Region」的内存布局
ZGC 将堆划分为多个大小固定的 Region(区域),支持三种尺寸:
Small Region:2MB(存储小对象);
Medium Region:32MB(存储中等对象);
Large Region:大小不固定(等于大对象大小,避免大对象跨 Region)。 Region 可动态创建 / 销毁,内存利用率更高。
(2)染色指针(Colored Pointers)
ZGC 最核心的创新,将对象的元数据(如标记状态、所属 Region)存储在指针的空闲位中(64 位系统指针仅使用 48 位地址,剩余 16 位可复用),而非对象头:
优势:无需修改对象内存即可标记对象,避免 CMS/G1 的「写屏障」开销;
核心状态位:
Marked0/Marked1:标记对象是否存活;
Remapped:标记指针是否已重映射到新地址。
(3)并发处理全流程
ZGC 几乎所有阶段(标记、重映射、压缩)均为并发执行,仅在「指针切换」等极短操作时触发微秒级 STW:
ZGC 回收周期:
1. 初始标记(STW,微秒级):标记 GC Roots 直接引用的对象;
2. 并发标记:遍历对象图,标记所有存活对象(染色指针);
3. 重新标记(STW,微秒级):处理并发标记期间的漏标;
4. 并发重映射:更新所有指向旧 Region 的指针;
5. 并发压缩:将存活对象移动到新 Region,释放旧 Region。
2. ZGC 核心特性
| 特性 | 说明 |
| 超低 STW | 所有 STW 操作均在 10ms 内,且与堆大小无关(即使堆为 TB 级); |
| 并发回收 | 标记、压缩、重映射全并发,几乎不占用应用线程时间; |
| 无内存碎片 | 基于复制的压缩机制,彻底解决内存碎片问题; |
| 可扩展 | 支持 8MB ~ 4TB 堆内存,适配从单机到大型服务器的场景; |
| 多平台支持 | 支持 Linux/x86_64、Linux/AArch64,JDK 17 后支持 Windows/AArch64; |
3. ZGC 启用与参数配置
(1)启用 ZGC(JDK 11+)
运行
# JDK 11-14(实验性,需加 --enable-preview)java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar app.jar
# JDK 15+(正式特性,无需预览)java -XX:+UseZGC -jar app.jar
(2)核心调优参数
运行
# 设置堆内存(ZGC 建议堆不小于 4GB)-Xms16G -Xmx16G
# 设置 Region 大小(默认自动,也可手动指定)-XX:ZHeapSize=16G -XX:ZSmallRegionSize=2M -XX:ZMediumRegionSize=32M
# 设置并发线程数(默认 CPU 核心数的 1/8)-XX:ZConcGCThreads=8
# 开启 ZGC 日志(推荐)
-Xlog:gc*=info:file=zgc.log:time,uptime,pid,tid
# 禁用偏向锁(ZGC 与偏向锁不兼容,JDK 17 已修复)-XX:-UseBiasedLocking
4. ZGC 适用场景
(1)推荐场景
超大堆内存应用(如 32GB+ 堆);
对延迟敏感的服务(如金融交易、实时风控、游戏服务器);
要求 99.999% 可用性的核心系统;
替代 CMS/G1 无法满足低延迟要求的场景。
(2)不推荐场景
小内存应用(堆 < 4GB):ZGC 初始化开销高于 G1;
纯吞吐量优先的批处理任务(Parallel GC 更高效);
旧版本 JDK(<11)或非 Linux 平台(如 Windows/x86_64)。
三、ZGC 与 G1/CMS 的对比
| 维度 | ZGC | G1 | CMS |
| STW 时间 | <10ms(与堆无关) | 几十毫秒(随堆增大) | 毫秒级(并发阶段无) |
| 内存碎片 | 无(压缩) | 少量(部分压缩) | 严重(无压缩) |
| 堆大小支持 | 8MB ~ 4TB | 最大约 100GB | 最大约 64GB |
| 并发程度 | 全流程并发 | 部分并发 | 标记并发、清除串行 |
| 内存利用率 | 高(动态 Region) | 中等 | 高(无压缩) |
| CPU 开销 | 较高(并发线程) | 中等 | 中等 |
四、ZGC 演进与未来
JDK 11:首次引入 ZGC(实验性),仅支持 Linux/x86_64;
JDK 15:ZGC 正式发布,支持压缩指针、大页面;
JDK 17:ZGC 成为 LTS 特性,支持 Windows/AArch64、禁用偏向锁自动适配;
JDK 21:ZGC 优化并发压缩、降低 CPU 开销,支持更大堆(8TB 预览)。
总结
基础 GC:解决内存自动回收问题,但传统收集器在大堆、低延迟场景下存在瓶颈;
ZGC:通过染色指针、并发全流程、Region 内存布局等创新,实现了「超大堆 + 超低延迟」的突破,是高可用、低延迟 Java 应用的首选收集器;
选型建议:
小堆、吞吐量优先 → Parallel GC;
中等堆、平衡延迟与吞吐量 → G1;
大堆、超低延迟 → ZGC。
ZGC 已在金融、电商、云计算等核心场景大规模落地,是 Java 高性能架构的重要基石。
Java GC 与 ZGC 全面解析

浙公网安备 33010602011771号