07-G1&ZGC

type
status
date
slug
summary
tags
category
icon
password

1️⃣ G1收集器(-XX:+UseG1GC)

G1 垃圾收集器(Garbage-First GC,启用参数为 -XX:+UseG1GC)是 Oracle JDK 中面向服务端应用的高性能垃圾收集器,自JDK9起成为默认GC。G1的设计目标是:高吞吐、可预测的停顿时间、低碎片化,特别适合大堆内存环境(如 4GB 以上)。

1. G1 的核心设计理念

1️⃣ 区域划分(Region)
  • G1 将堆划分为多个等大小的 Region(区域),每个 Region 一般为 1MB ~ 32MB,默认是 2048 个 Region
  • 每个 Region 会被动态标记为不同角色:
    • Eden 区
    • Survivor 区
    • Old 区
    • Humongous 区:存放大对象(大于 Region 大小一半的对象)
2️⃣ 分代收集,但不固定空间
  • G1 仍然是分代 GC,分为 Young Generation 和 Old Generation。
  • Young / Old 的空间不是连续的,而是由多个分散的 Region 动态组成

2. G1 的垃圾收集过程

1️⃣ Young GC(Minor GC)
  • 回收 Eden + 部分 Survivor,对象晋升到 Old。
  • 采用 并发回收 + 多线程处理,低停顿。
2️⃣ Mixed GC(G1 的关键特点)
  • 回收 Young 区 + 一部分 Old 区
  • 优化停顿时间和回收效率的平衡:根据“垃圾优先”策略,优先回收垃圾多的 Region
  • G1 不再等到 Old 区满再触发 Full GC,而是通过 Mixed GC 做预防式回收。
3️⃣ Full GC(最后手段)
  • 使用 Serial Old GC 实现,单线程,效率低,应尽量避免触发

3. G1的核心机制

1️⃣ Remembered Set(RSet)
  • 记录引用跨 Region 的引用关系
  • 每个 Region 都维护一个 RSet,记录“谁引用了我”。
  • 写屏障 + 卡表机制更新 RSet(类似传统 GC 中的 Card Table + Remembered Set 机制)。
2️⃣ 并发标记阶段(Concurrent Marking)
阶段
描述
初始标记(Initial Mark)
标记 GC Roots 引用的对象,只扫描 Survivor 区;伴随 Young GC 发生,停顿。
并发标记(Concurrent Mark)
标记整个堆中存活对象(Tracing GC Roots)。并发进行。
最终标记(Remark)
修正并发标记期间发生的变动。Stop-The-World。
筛选回收(Cleanup)
计算每个 Region 的存活率,筛选可回收的 Region,决定 Mixed GC 回收计划。

4. G1的目标与优势

特性
描述
可预测的停顿时间
支持参数 -XX:MaxGCPauseMillis=目标毫秒数 指定期望最大停顿时间(默认 200ms)
并发回收
大量操作在应用线程运行时并发进行,减少 STW(Stop The World)时间
减少碎片
回收以 Region 为单位,天然具备压缩能力,避免老年代碎片化问题
无需手动调优分代比例
自动管理 Eden/Survivor/Old 空间比例

适用场景与注意事项

适合:
  • 大堆(4GB 以上)
  • 停顿时间敏感的在线系统(如 Web 服务、API 网关)
  • 想避免频繁 Full GC 的场景
⚠️ 不适合:
  • 嵌入式、低内存场景
  • 停顿时间毫秒级别严格控制(如高频交易),可能需使用 ZGC/SHENANDOAH

2️⃣ ZGC收集器(-XX:+UseZGC)

ZGC(Z Garbage Collector,启用参数为 -XX:+UseZGC)是一种低延迟(Low Latency)、可扩展(Scalable)、并发(Concurrent)的垃圾收集器目标是在任意堆大小下都能将 GC 停顿时间控制在 1ms 以下,适用于延迟敏感型大内存系统
特性
说明
目标
停顿时间不超过 1ms(即使在 TB 级堆上)
分代模型
默认是 非分代 GC(JDK 15 起支持分代)
并发性
几乎所有 GC 工作都在并发阶段完成,最大限度减少 STW
GC 类型
并发标记、并发转移、并发重映射
适用平台
JDK 11+ 开始引入,JDK 15 起稳定;Linux/Windows/macOS 均支持

1. ZGC 的核心原理

基于“染色指针”(Colored Pointer)
ZGC 最大的技术创新是染色指针(colored pointer)
  • 将对象头(64 位地址的高位)中的部分位用于存储元信息(如标记状态、重定向信息)。
  • 实现无需停顿的标记与重定向。
  • 所有对象访问都通过load barrier(加载屏障)处理其元信息。
并发阶段为主,停顿极短,只有两个 STW:初始标记、重定位开始,耗时通常 <1ms。
阶段
是否 STW
描述
Mark Start
STW(短暂停顿)
初始标记 GC Roots
Mark
并发
遍历堆中所有活对象(并发标记)
Relocate Start
STW(短)
准备对象迁移
Relocate
并发
将对象移动到新位置(并发转移)
Remap
并发
修复指向旧对象的引用

1. 颜色指针

在 ZGC 中,颜色指针是指 在对象引用的高位中嵌入标记位(Metadata),这些位用于表示对象的 GC 状态,例如:
功能
说明
标记对象是否存活
比如对象是否被标记过
标记对象是否已经转发(重定位)
用于并发拷贝阶段
标记使用的是哪一代页表(Remap Table)
实现转发指针
功能
示例
并发标记
标记对象是否存活
转发(relocation)
判断对象是否已迁移
多版本地址映射(Remap)
管理从旧地址到新地址的页表映射关系
压缩地址空间(heap)
使用高位做标志而非扩大地址空间
虽然名字都提到“颜色”,但:
  • 三色标记法:是一种标记算法(白/灰/黑)
  • 颜色指针:是 ZGC 实现中的一种技术手段,与三色标记不直接等价
它们都涉及“颜色”概念,但一个是抽象算法,另一个是具体实现技术。
 
ZGC 能这样做的原因:
  • 现代 64 位 CPU 并不使用完整的 64 位地址空间(通常只用 48 ~ 52 位)
  • 上位的若干位未用,可用于扩展和标记
  • ZGC 在 Linux/x86-64 上通过虚拟地址映射实现这种优化

2. Load Barrier(加载屏障)

ZGC 对所有的对象引用读取操作都加了一个透明的 Load Barrier
该屏障能判断:
  • 当前引用是否指向旧地址
  • 如果是,就 remap 到新地址(通过转发表)
  • 如果对象已被搬迁,就更新引用为新地址
🔁 这是实现 对象地址不变承诺 的关键技术。

3. 转发表(Remap Table)

  • 存储对象从旧地址 → 新地址的映射
  • Load Barrier 会在 remap 时访问这张表
  • 实现“地址永远可达”

4. 并发重定位(Concurrent Relocation)

  • 搬迁对象时,不停止应用线程
  • 通过转发表、Load Barrier 让访问不会出错
  • 避免大规模 STW 压缩的代价

2. ZGC 垃圾回收流程

1️⃣ Initial Mark(初始标记)
  • STW(极短暂)
  • 标记 GC Roots
2️⃣ Concurrent Mark(并发标记)
  • 从 GC Roots 开始扫描整个对象图,标记可达对象
  • 并发进行,不阻塞应用线程
3️⃣ Concurrent Prepare for Relocate(并发准备重定位)
  • 计算哪些区域需要移动(碎片整理)
  • 构建转发表(Remap Table)
4️⃣ Relocation Set Selection(选择要压缩的内存区域)
  • 找出可搬迁对象区域
5️⃣ Concurrent Relocate(并发重定位)
  • 将对象从原区域复制到新区域
  • 原对象记录转发地址(forwarding pointer)
6️⃣ Remap(访问时重映射)
  • 所有对旧对象地址的访问通过 Load Barrier 自动 remap 到新地址

3. ZGC 的参数配置

参数
说明
-XX:+UseZGC
启用 ZGC
-Xmx -Xms
设置堆大小(ZGC 适合大堆,推荐至少 8GB+)
-XX:+ZGenerational
启用 ZGC 的分代模式(JDK 15+ 支持)
-XX:ZUncommitDelay=<秒>
多久释放未使用内存(默认 300 秒)
-XX:MaxHeapFreeRatio
空闲内存百分比过高则回收

4. ZGC 的优势与限制

优势
项目
描述
极低延迟
停顿时间 < 1ms,即使在 TB 级堆上
并发性强
所有关键阶段均为并发,极少暂停
无碎片
搬迁对象后压缩堆,避免内存碎片
可扩展性强
支持大堆(最大可达数 TB)
自动内存回收
支持堆内存自动收缩(按需归还操作系统)
⚠️ 局限
限制项
描述
内存占用较大
因为需要维护元信息和备用空间
依赖 load barrier
性能依赖于平台和指针压缩实现
垃圾产生速率高时表现受限
如果对象分配和存活速率远超回收速率,仍可能 OOM
JDK 版本要求高
建议使用 JDK 17+(长期支持),ZGC 更加稳定

5. 典型使用建议

适用场景:
  • 大堆、高吞吐场景(8GB ~ 数 TB)
  • 停顿时间敏感型应用(金融、游戏、在线服务)
  • 高并发、低延迟系统(微服务、大数据流处理)
不推荐场景:
  • 小内存、嵌入式系统
  • GC 暂停时间不敏感的批处理任务

3️⃣ ZGC vs G1GC 对比

特性
ZGC
G1GC
停顿时间
低于 1ms
目标时间(默认 200ms)
堆支持大小
数 TB
推荐 <= 32GB
是否分代
默认不分代(支持分代)
分代
并发能力
几乎全并发
部分并发
实现复杂度
高(依赖 load barrier)

ZGC 与其他 GC 的对比

特性
ZGC
G1GC
CMS
Shenandoah
最小 STW
✅ <10ms
❌ 可能 100ms+
❌ 可能秒级
✅ 极短
并发标记
并发移动对象
❌(STW copy)
适合大堆(TB)
⚠️ 最大几百 GB
多线程并发
⚠️
 
上一篇
06-垃圾收集底层算法
下一篇
01-MySQL数据结构
Loading...