bigywater.tech
Java · 295

ZGC 彩色指针:引用元数据如何参与并发回收

ZGC 把「颜色」放进指针里,所以要把同一块内存映射多份?这篇从 GC 日志里的地址空间数字出发,对比 JDK 21 单代、分代和 JDK 27,再量暂停时间与读引用的代价。

×3
JDK 21 单代 ZGC 的地址空间倍数(分代与 JDK 27 没有)
0.022 ms
三种 ZGC 配置在本负载下的最大暂停(G1 是 15.047 ms)
97.7 → 88.1 ns
随机链表遍历每节点耗时:JDK 21 单代 ZGC 对比 JDK 27 ZGC

地址空间

实测 · 本机执行输出
  JDK 21 ZGC(默认,单代):
    -Xmx256m  Address Space Size: 4096M x 3 = 12288M
    -Xmx512m  Address Space Size: 8192M x 3 = 24576M
    -Xmx1g    Address Space Size: 16384M x 3 = 49152M
    -Xmx4g    Address Space Size: 65536M x 3 = 196608M
    其它: ['Using legacy single-generation mode', 'Address Space Type: Contiguous/Unrestricted/Complete']
  JDK 21 ZGC 分代(-XX:+ZGenerational):
    -Xmx256m  Address Space Size: 4096M
    -Xmx512m  Address Space Size: 8192M
    -Xmx1g    Address Space Size: 16384M
    -Xmx4g    Address Space Size: 65536M
    其它: ['Address Space Type: Contiguous/Unrestricted/Complete']
  JDK 27 ZGC:
    -Xmx256m  Reserved Space: limit 4096G, desired 4G, requested 4G
    -Xmx512m  Reserved Space: limit 4096G, desired 8G, requested 8G
    -Xmx1g    Reserved Space: limit 4096G, desired 16G, requested 16G
    -Xmx4g    Reserved Space: limit 4096G, desired 64G, requested 64G
    其它: ['Reserved Space Type: Contiguous/Unrestricted/Complete']

暂停时间

实测 · 本机执行输出
  JDK 21 ZGC(默认,单代)                  暂停  522 次;最大   0.009 ms;平均  0.003 ms;6 秒内分配次数 29.2 百万
  JDK 21 ZGC 分代(-XX:+ZGenerational)  暂停 2124 次;最大   0.016 ms;平均  0.003 ms;6 秒内分配次数 14.1 百万
  JDK 27 ZGC                         暂停 3605 次;最大   0.022 ms;平均  0.003 ms;6 秒内分配次数 22.2 百万
  JDK 21 G1(对照)                      暂停  866 次;最大  15.047 ms;平均  2.870 ms;6 秒内分配次数 20.1 百万

读引用代价

实测 · 本机执行输出
  JDK 21 ZGC(默认,单代)                  [97.73, 96.35, 98.39] ns/节点  中位 97.73
  JDK 21 ZGC 分代(-XX:+ZGenerational)  [95.99, 96.29, 96.21] ns/节点  中位 96.21
  JDK 27 ZGC                         [88.56, 86.82, 88.1] ns/节点  中位 88.1
  JDK 21 G1(对照)                      [87.32, 87.37, 87.0] ns/节点  中位 87.32

分步演示

ZGC 与着色指针
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12 与 JDK 27,Apple Silicon;暂停次数与分配次数在重复运行间有小幅波动
    • 没有验证:地址空间 ×3 与「标记 0、标记 1、重映射」三种颜色之间的对应(只是观察到 ×3 的数字与分代后消失,没有用 vmmap 检查实际映射)、指针里颜色位的具体位置、读屏障与存储屏障的机器码、大堆(TB 级)下的行为、Linux 上的差异
    京ICP备2026067502号-1京公网安备11010502063487号