商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > JVM中Shenandoah与G1在跨Region引用维护及并发标记阶段的相似与相异性

JVM中Shenandoah与G1在跨Region引用维护及并发标记阶段的相似与相异性

  发布于2026-07-09 阅读(0)

扫一扫,手机访问

Shenandoah使用连接矩阵替代G1的记忆集以降低跨Region引用维护开销:前者为全局二维布尔表,仅记录Region级引用关系,避免伪共享和高内存占用;后者为每个Region独立维护的哈希表,精度高但开销大。

JVM中Shenandoah与G1在跨Region引用维护及并发标记阶段的相似与相异性

Shenandoah 与 G1 在跨 Region 引用维护和并发标记阶段的关系,既有明显的继承痕迹,也藏着各自的设计取舍——前者把降低开销放在首位,全力支持全并发;后者则更看重分代精度与吞吐的平衡。

先说跨 Region 引用维护这块。G1 依赖的是每个 Region 独立维护的“记忆集”,本质上是一个哈希表结构,用于记录本 Region 中对象指向其他 Region 的引用。这种细粒度方案确实能精准定位脏卡,但代价不菲:它会占用堆内存的 10%–20%,而且频繁更新时很容易引发伪共享和写屏障开销。

Shenandoah 则完全放弃了记忆集,转而采用全局的“连接矩阵”——一张二维布尔表,行和列都代表 Region。如果 Region A 中有任意对象引用了 Region B 中的对象,就在 matrix[A][B] 标记为 true。巧妙之处在于,连接矩阵不追踪具体字段或对象,只记录 Region 级的引用关系,颗粒度更粗,每个 Region 也不需要单独计算和同步维护,内存开销因此显著降低。当然,粗粒度也意味着扫描成本更高,但因为整个 GC 过程是并发的,多线程并行可以把这笔成本摊薄,这实际上是一种对吞吐的主动妥协。

并发标记阶段:流程一致,但目标约束不同

两者都采用了三色标记法加上 SATB 快照机制,阶段划分非常相似:先初始标记暂停用户线程,再在用户线程运行中并发遍历对象图,最后通过短暂停顿处理剩余增量引用。真正的区别在于标记结果后续怎么用。

  • G1 的标记结果服务于分代回收决策,用来区分新生代和老年代 Region,并决定哪些 Region 进入年轻代 GC 或混合 GC。
  • Shenandoah 不分代,标记结果直接用来筛选“回收价值最高”的 Region,组成回收集,这个集合可能包含任意 Region,没有年龄假设。
  • 由于 Shenandoah 后续要并发移动对象,其并发标记还必须配合 Brooks 指针与读屏障,确保标记过程中对象地址变更不会导致漏标。

实际影响:停顿时间与适用场景分化

连接矩阵、无分代、并发整理——这三个特性组合在一起,让 Shenandoah 能把 STW 时间压到毫秒级,典型值在 5 到 50 毫秒之间。特别适合堆容量大、延迟敏感的场景,比如实时风控、高频交易网关。而 G1 虽然从 JDK 17 开始持续优化,但记忆集维护和部分 STW 回收阶段仍然会导致停顿更长,通常落在 10 到 500 毫秒这个区间,更适合对吞吐略高要求、能接受中等延迟的通用服务。

两者在标记逻辑上共享了大量代码,这说明 Shenandoah 确实是 G1 的演进而非推倒重来——只是把“如何减少停顿”放在了绝对优先的位置。

本文转载于:https://www.php.cn/faq/2793764.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注