ZGC并发压缩采用增量式Region迁移,通过染色指针与读屏障实现边运行边整理,仅需两次亚毫秒STW,空闲空间作为弹性缓冲池支持低碎片、高吞吐分配。

ZGC 的并发压缩不是“一次性搬完所有对象”,而是把堆拆成小块区域(Region),每次只挑一部分做迁移,整个过程和你的应用线程一起跑,几乎不打断业务。
压缩动作是分片、增量、后台流水线式的
ZGC 把堆划分为固定大小的 Region(比如 2MB/4MB/32MB),每次 GC 只选其中一小批进行重定位。它不等所有存活对象都准备好才动手,而是边标记、边转移、边更新引用——每个子任务耗时极短,分散在毫秒级时间片里执行。
- 例如:256GB 堆中,某次 GC 可能只迁移约 5% 的 Region(约 12GB),但不是一口气搬完,而是拆成几十个并发子任务轮流执行
- 迁移过程中,应用线程照常分配新对象、读写旧对象,ZGC 通过读屏障自动修正访问路径
- 没有全局 Stop-The-World 压缩阶段,只有两次极短 STW(初始标记和重定位准备),通常各不到 1ms
压缩依赖染色指针 + 读屏障,不扫堆头也能安全重定向
ZGC 不靠扫描对象头来判断是否已迁移,而是把状态信息直接编码进对象引用本身(即“染色指针”)。只要程序读一个指针,JVM 就触发读屏障检查——如果指向的是旧地址,就现场跳转到新位置并更新引用。
- 避免了传统压缩器必须暂停应用、遍历整个堆更新引用的开销
- 标记、转移、重映射三个关键环节全部支持并发,真正实现“边用边整”
- 即使某个对象刚被迁移,下一毫秒就被业务线程访问,也能即时响应,不会出错或卡顿
空闲空间不是被“填满”,而是作为弹性缓冲池参与压缩调度
ZGC 不追求堆内存 100% 利用率,反而主动保留一定比例的空闲 Region。这些区域不是浪费,而是为并发压缩提供快速落点——当要转移一批对象时,能立刻找到干净目标区,不用等合并或等待锁。
- Region 大小统一,分配按整块走,天然规避内部碎片
- Marked0 / Marked1 / Remapped 三视图隔离逻辑状态,当前分配视图之外的“空闲”,其实是待回收或已回收的物理页
- 操作系统层面的内存提交(mmap)是懒加载的,虚拟空闲 ≠ 物理闲置,实际内存占用由负载驱动
压缩效果体现在低碎片+高分配吞吐,而非“零空闲”
ZGC 的压缩目标从来不是消灭所有空闲空间,而是让堆始终保持可预测的连续性:新对象总能快速拿到整块 Region,长期运行不因碎片导致分配失败或延迟飙升。
- 碎片控制靠的是定期、轻量、局部的 Region 级整理,不是全堆大扫除
- 哪怕堆使用率只有 60%,只要空闲 Region 分布合理,就能支撑高频分配
- 停顿时间稳定在个位数毫秒,且与堆大小无关——这才是并发压缩真正落地的价值

















