JDK 17/21 新特性 ZGC
ZGC(Z Garbage Collector):
ZGC(Z Garbage Collector)是 Oracle 开发的一款低延迟垃圾收集器,专为 Java 应用设计,目标是在大堆内存(从几 MB 到 16 TB)下实现极短的 GC 停顿时间(通常不超过 10 ms,JDK 17+ 可达亚毫秒级)
在17中默认仍是G1 GC,在21中默认为ZGC,并增加分代。
一、核心设计目标
1. 暂停时间不超过 10ms
无论堆内存多大(从几百 MB 到几 TB)
无论存活对象多少
暂停时间都保持在毫秒级
2. 停顿时间与堆大小无关
传统 GC:堆越大,停顿时间越长
ZGC:通过并发处理,打破这个关系
3. 吞吐量损失可控
目标:吞吐量降低不超过 15%
二、关键技术原理
1.分代管理(Generational)
年轻代区域 (Young Generation Regions)
└─ 新创建的对象
老年代区域 (Old Generation Regions)
└─ 经过多次 GC 后存活的对象
分代假设:大多数对象朝生夕死
好处:优先回收年轻代,减少每次 GC 的工作量
2.区域划分(Region-based)
堆内存 → 多个 Region(每个 2MB-32MB)
├─ Young Region
├─ Old Region
└─ Large Region(大对象专用)
不再使用连续的 Eden/Survivor/Old 分区
以 Region 为单位进行回收和分配
3.⭐染色指针(Colored Pointers)
这是 ZGC 最核心的创新!
普通指针:64 位地址
├─ 64 位全部用于寻址
染色指针:64 位中
├─ 42 位:实际地址(支持 4TB 堆)
├─ 4 位:标记位(颜色)
│ ├─ Bit 0: Finalizable
│ ├─ Bit 1: Remapped
│ ├─ Bit 2: Marked0
│ └─ Bit 3: Marked1
└─ 18 位:保留
四种颜色状态:
白色(White):未标记
红色(Red):已标记,未移动
蓝色(Blue):已标记,已移动
绿色(Green):已标记,已移动,已引用更新
4.读屏障(Load Barriers)
// 应用代码
Object obj = someReference; // 读取对象引用
// ZGC 插入读屏障
if (obj.color == RED) {
// 对象已标记但未移动
// 触发标记或重映射操作
}
作用:
在应用读取对象时检查指针颜色
如果发现对象需要移动,立即完成移动和引用更新
将 GC 工作分散到应用线程中并发执行
5. SATB(Snapshot At The Beginning)原始快照
解决并发标记期间的引用变化问题:
标记开始时:记录所有存活对象
标记过程中:
- 应用修改引用(A→B)
- ZGC 记录 A 的旧值(写入屏障)
- 确保 B 不会被遗漏
三、GC 工作流程
完整 GC 周期(GC Cycle)
┌─────────────────────────────────────┐
│ Phase 1: 标记 (Mark) │
│ - 初始标记(STW,< 1ms) │
│ - 并发标记(与应用并行) │
│ - 最终标记(STW,< 1ms) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Phase 2: 预备 (Prepare) │
│ - 选择要回收的区域 │
│ - 计算存活对象 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Phase 3: 复制 (Relocate) │
│ - 并发复制存活对象 │
│ - 使用读屏障处理引用 │
│ - 短暂 STW 切换指针 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Phase 4: 归还 (Return) │
│ - 释放旧区域 │
└─────────────────────────────────────┘
详细步骤说明
1. 标记阶段
[STW] 初始标记
└─ 标记 GC Roots 直接引用的对象
[并发] 并发标记
└─ 遍历对象图,标记所有存活对象
└─ 使用 SATB 处理引用变化
[STW] 最终标记
└─ 处理少量遗留的标记任务
└─ < 1ms
2. 复制阶段
[并发] 选择存活对象 → 新 Region
复制到新地址
更新指针颜色为 BLUE
[STW] 指针切换(< 1ms)
将所有指向旧对象的引用 → 新对象
[并发] 应用继续运行
读屏障处理残留的旧引用
四、为什么 ZGC 能做到低延迟
1. 并发化
传统 GC: [STW]████████████[运行]
ZGC: [运行]░░░░░░░░[STW 1ms][运行]
░ = 并发执行,不暂停应用
2. 分代回收
年轻代 GC:只回收年轻代区域(速度快)
混合 GC: 年轻代 + 部分老年代(可控)
完整 GC: 整个堆(极少发生)
3. 读屏障分摊
GC 工作不再集中在 STW 期间
而是分散到应用的每次对象读取操作中
五、简单总结
ZGC 的核心思想:
用 CPU 换延迟 —— 通过并发执行和读屏障,将 GC 工作分散到应用运行过程中,从而避免长时间停顿。
三个关键词:
染色指针 - 在指针中存储状态信息
读屏障 - 在读取对象时触发 GC 操作
并发化 - 大部分工作与应用程序并行执行
这种设计使得 ZGC 成为目前 Java 生态中最先进的垃圾回收器之一,特别适合对延迟要求极高的场景(如金融交易、实时系统、Web 服务等)。
更多推荐




所有评论(0)