zgc并发重定位通过精准region选择、zworker多线程搬运、读屏障自动转发及着色指针元数据内嵌,实现对象迁移全程无stw:重定位前完成标记确保不漏迁,过程中旧地址仅可读并自动跳转,新分配严格隔离,所有状态与转发信息均硬件友好编码于指针和对象头中。

ZGC 的并发重定位(Concurrent Relocation)不是简单的“复制+更新指针”,而是以零停顿为目标、软硬件协同驱动的一整套内存管理闭环。它的核心逻辑在于:让对象迁移在应用线程持续运行的同时发生,且对业务代码完全透明——不依赖全局暂停,也不要求应用线程配合同步。
1. 重定位的触发与范围决策
重定位不是全堆扫描式搬运,而是有明确目标的“精准搬迁”:
- 由并发预备重定位阶段(Concurrent Prepare for Relocation)提前选定待回收 Region:通常是内存利用率低、碎片化严重或长期未被访问的 Region
- Region 按大小分为 Small / Medium / Large 三类;Large Region 多承载大对象,重定位开销高但频次低;Small Region 频次高但单次轻量——ZGC 会动态权衡调度
- 从 JDK 16 起支持in-place relocation(本地重定位):若目标页仍有空闲空间,对象可直接在原 Region 内重新排列,避免跨页拷贝,显著降低内存带宽压力
2. 并发执行与线程协作机制
重定位工作由 ZGC 自身的并发工作线程(ZWorkers)承担,不再依赖单一线程:
- 通过 -XX:ZWorkers=N 可显式配置并发线程数,默认值为 CPU 核心数 × 0.5(向上取整),适用于 TB 级堆的吞吐调节
- ZWorker 线程独立扫描待重定位 Region,执行 memcpy + 转发指针写入;期间应用线程照常运行,无需等待
- 当应用线程通过旧地址访问对象时,读屏障(Load Barrier)自动拦截并完成转发:检查着色指针状态 → 若已重定位则跳转至新地址 → 同时可能触发“自愈式更新”(将旧引用当场修正)
3. 地址管理与元数据零开销保障
整个过程不依赖额外的映射表或哈希结构,靠硬件友好的编码实现元数据内嵌:
- 着色指针(Colored Pointers):利用 64 位地址高位(Linux/x64 中第 42–47 位)直接存储对象状态(如 remapped、marked0/1、finalizable)
- 转发信息不存于堆外结构,而是写入对象头中预留的 forwarding pointer 字段;读屏障仅需一次原子读+条件跳转,延迟控制在纳秒级
- 所有重定位操作均基于页对齐地址,配合大页(-XX:+UseLargePages)可减少 TLB miss,但需注意 NUMA 绑定,否则跨节点内存访问反而拖慢速度
4. 安全性与一致性边界控制
并发不等于无序,ZGC 用轻量级同步和阶段栅栏保证语义正确:
- 重定位开始前,必须完成并发标记与再标记(Remark),确保所有存活对象已被识别,避免漏迁
- 重定位过程中,任何新分配都严格落在空闲或新分配页中,旧 Region 进入只读或逐步冻结状态
- ZGC 不禁止 Mutator 修改对象字段,但所有修改均作用于新地址副本;旧地址仅保留转发能力,不可写











