当前位置: 首页 > news >正文

低延迟垃圾收集器:挑战“不可能三角”

----------- 先赞后看 👍 效果翻倍 🔥 ----------------

在开始之前,必须再次强调 “不可能三角”内存占用、吞吐量、延迟,三者难以同时完美。

传统的垃圾收集器(如 Serial, Parallel, CMS, G1)在堆内存变大时,停顿时间(Latency)也会显著变长,因为它们总有一些阶段需要“Stop The World”(挂起所有用户线程)来完成清理工作。这对于需要快速响应的应用(如实时交易、大数据平台、微服务)是无法接受的。

Shenandoah 和 ZGC 的目标就是打破这个魔咒,实现在任何堆大小下(比如 4TB),停顿时间都能被严格控制在十毫秒以内,同时尽可能减少对吞吐量的影响。

它们实现这一目标的核心理念是:将最耗时的“对象移动”阶段也并发化。这听起来简单,但实现起来极其复杂,因为在你移动对象的同时,用户线程可能正在读写它。两者解决方案不同,但都极其精妙。


Shenandoah: “搬家队长”与“转发牌”

你可以把 Shenandoah 想象成一个高效的搬家队长,它的核心绝招是 “转发指针”(Brooks Pointer)

1. 它是谁?

  • 由 RedHat 开发,是 OpenJDK 的“养子”,OracleJDK 中不包含它
  • 你可以把它看作是 G1 的激进并发版,架构和 G1 很像(基于 Region 的堆布局),共享部分代码。

2. 它如何实现并发搬家?(核心原理)

想象一下,你要给一个正在营业的超市换货架,顾客还在不停买东西。你怎么做?

Shenandoah 的解决方案是:给每个商品(对象)挂上一个“转发牌”

  1. 准备工作:在每个对象内部,额外开辟一个小空间(在对象头前),里面存着一个地址。正常情况下,这个地址指向对象自己,就像商品上挂着一个写着“我在这里”的牌子。

  2. 开始搬家(并发回收阶段):Shenandoah 启动一个并发线程,悄悄地把需要回收的区域(Region)里的存活对象复制到新区域。这整个过程是不停止营业(用户线程)的

  3. 更新地址牌:对象复制完成后,Shenandoah 只做一件事:修改旧对象上的那个“转发牌”,把上面的地址从“旧对象”改为“新对象”的地址。注意:它不会去更新所有指向这个旧对象的引用

  4. 顾客访问(读/写屏障):这就是关键所在!Shenandoah 在 JVM 中设置了“哨兵”(读屏障和写屏障)。每当用户线程(顾客)要访问一个对象时,哨兵会先拦截这次访问,检查一下这个对象上的“转发牌”。

    • 如果牌子指向自己:说明没搬过家,直接访问。
    • 如果牌子指向别处:说明这个对象是旧对象,已经搬走了。哨兵会自动地、悄悄地根据牌子上的新地址,去访问新对象,并把这次访问的结果返回给用户。同时,它还会顺手把这个引用本身的值更新成新地址(只有第一次需要转发,后续就直接访问新对象了)。这个过程对用户线程是完全透明的。

为什么能控制停顿?
因为最耗时的“复制对象”和“更新引用”工作都被并发线程和“哨兵”(屏障)分担了。那些必需的短暂停顿(初始标记、最终标记等)只处理少量核心信息(GC Roots),与堆大小无关,所以非常短。

3. 优缺点

  • 优点:停顿时间极短,与堆大小脱钩。
  • 缺点“哨兵”(尤其是读屏障)带来的开销非常大。因为每一次对象读取操作都要经过这个检查步骤。这导致 Shenandoah 的吞吐量损失通常是三者中最大的

ZGC: “魔法指针”与“自愈能力”

ZGC 的思路更加科幻。它不像 Shenandoah 那样给对象挂牌子,而是直接给指针(内存地址)施了魔法,它的核心是 染色指针(Colored Pointer)

1. 它是谁?

  • 由 Oracle 亲儿子开发,血统纯正,OpenJDK 和 OracleJDK 都包含。
  • 它的设计理念源自传说中的 Azul C4 收集器,非常前沿。

2. 它如何实现并发搬家?(核心原理)

继续用超市搬家的比喻。ZGC 的做法不是挂牌子,而是它有一种“魔法墨水”,可以直接在写有商品位置的导购图(指针)上做标记

  1. 魔法墨水:在 64 位系统中,我们其实用不了那么大的地址空间。ZGC 巧妙地利用了指针中未使用的比特位(比如高 4 位)来存储信息。这些信息包括:对象是否被标记、是否属于待回收集合、是否已被移动过。
    所以,ZGC 的指针不仅仅是地址,它本身就是携带元数据的。通过这个指针,ZGC 不用访问对象就能知道它的状态。

  2. 地址重映射(魔法地图):光在指针上写墨水,CPU 可不认账,它会把这些位也当成地址的一部分,会找错地方。ZGC 的解决方案是 多重映射:它通过操作系统的内存管理功能,将好几块不同的虚拟内存地址空间(比如,指针标志位是 0010 的地图和 0000 的地图)都映射到同一块真实的物理内存上。这样,无论指针上的“魔法墨水”怎么写,最终都能通过这张“魔法地图”找到正确的物理对象。

  3. 并发搬家与自愈:当 ZGC 要移动一个对象时:

    • 它并发地将对象复制到新 Region。
    • 它在旧对象的位置上留下一个“转发地址”(类似于转发表)。
    • 最关键的一步来了:当用户线程试图访问一个已经被移动的旧对象时,ZGC 的“哨兵”(读屏障)会被触发。这个哨兵一看指针上的“魔法墨水”(标志位),就知道“哦,这个对象搬走了”。于是它:
      1. 去旧位置上的“转发地址”里找到新地址。
      2. 直接把这个线程手中的指针值更新成新地址(并修正标志位)!
      3. 再去新地址访问对象。

    这个过程被称为 “自愈”(Self-Healing)这次访问之后,这个引用本身就已经被修正了,下次再访问就是直接访问新对象,没有任何额外开销。 这是它与 Shenandoah 每次访问都可能需要检查的关键区别。

3. 优缺点

  • 优点
    1. 停顿时间极短,同样与堆大小无关。
    2. “自愈”能力使得运行时开销远小于 Shenandoah,因此吞吐量表现通常比 Shenandoah 好得多,甚至接近 G1。
    3. 无需像 G1 那样维护记忆集,节省了内存。
  • 缺点
    1. 实现极其复杂,严重依赖底层操作系统特性(如多重映射)。
    2. 不支持分代收集(目前),可能导致浮动垃圾较多,抗突发流量能力稍弱。不过这是工程选择,并非技术不能实现。

总结与对比:你该选谁?

特性 Shenandoah ZGC
核心原理 转发指针 (Brooks Pointer) 染色指针 (Colored Pointer)
实现方式 在对象头前加额外指针 利用指针的未使用位存储元数据
关键机制 读屏障 + 写屏障 读屏障(目前无需写屏障)
引用更新 每次访问都可能需要转发检查 “自愈”,仅第一次访问慢
性能特点 低延迟,但吞吐量损失较大 低延迟,吞吐量损失很小
血缘关系 G1 的并发升级版 Azul C4 的 OpenJDK 实现
支持现状 仅 OpenJDK 包含 OpenJDK OracleJDK 都包含

如何选择?

  • 追求极致低延迟,且运行在 OpenJDK 上:两者都是绝佳选择。
  • 同时非常关心吞吐量性能:优先尝试 ZGC,它的性能表现通常更均衡。
  • 需要使用 OracleJDK 并获得商业支持:只能选择 ZGC
  • 应用分配速率极高,堆内存巨大:目前两者都可能因为不分代而面临浮动垃圾的压力,需要预留足够堆内存。这是所有不分代收集器的共性问题。

总而言之,Shenandoah 和 ZGC 都代表了 JVM 垃圾收集技术的最高水平,它们通过不同的魔法将延迟降低到了前人无法想象的程度。ZGC 凭借其“魔法指针”和“自愈”能力,在实现上更显优雅,性能开销也更小,是目前更受瞩目的未来之星。

http://www.wxhsa.cn/company.asp?id=6351

相关文章:

  • Java Heap Dump详解
  • 软件逆向入门理论
  • 鸿蒙应用开发从入门到实战(七):ArkTS组件声明语法
  • P1115 最大子段和
  • 麒麟系统关闭防火墙
  • P14003 [eJOI 2025] Reactions 解题报告
  • 计算机科学入门
  • Windows Server 2019开启远程桌面无法远程处理
  • 英语_阅读_This makes me crazy_待读
  • 一位华裔数学家40年目睹之怪现状:美国学生的数学为什么那么差?
  • 这些年轻科学家不再满足于“追赶美国”
  • 英语_阅读_
  • 聊聊理想的影像团队
  • 黑芝麻智能上半年亏损超7亿 CEO单记章去年薪酬高达1.66亿
  • 英语_阅读_BMI_待读
  • Flutter数据可视化:fl_chart图表库的高级应用
  • 教材大纲-Python
  • 2025 年 PHP 常见面试题整理以及对应答案和代码示例
  • 0130_中介者模式(Mediator)
  • 零门槛入局 AI 创业!瓦特 AI 创作者平台,让普通人轻松抓住风口
  • 基环树
  • 2025介绍1个简单好用免费的版权符号复制生成网站
  • 【GitHub每日速递 250917】69k 星标!这个 MCP 服务器大集合,竟能解锁 AI 无限可能?
  • WPF 通过 WriteableBitmap 实现 TAGC 低光增强效果算法
  • 最新学王点读笔破解教程2025
  • css-3
  • 基于 RQ-VAE 的商品语义 ID 构建及应用案例
  • U3D 动作游戏开发中数学知识的综合实践案例
  • 删除根目录前的准备
  • Player Mini MP3 模块播放音乐