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 服务等)。

Logo

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

更多推荐