如何从图论视角推导 ZGC 并发标记期活对象图遍历算法在硬件并发线程下的高能去重

酷明大大_5806

酷明大大_5806

2026-05-22

882人浏览

原创

zgc并发标记通过三色标记+着色指针+读屏障实现硬件级协同去重,避免重复扫描与漏标;以页面为单位并行遍历,确保活对象图全覆盖且低停顿。

如何从图论视角推导 zgc 并发标记期活对象图遍历算法在硬件并发线程下的高能去重

ZGC 并发标记期的活对象图遍历,本质是图论中“从 GC Roots 出发的可达性遍历”在并发环境下的安全实现。它不追求传统意义上的“去重”,而是通过硬件级协同机制规避重复工作、防止漏标——这才是“高能去重”的真实含义:不是事后筛重,而是一开始就让多个线程天然不重叠、不遗漏。

可达性图结构决定遍历起点与边界

Java 堆在图论中是一个有向图 G = (V, E),其中:

  • V 是所有对象(含 GC Roots),每个对象是图中一个顶点;
  • E 是引用关系,若对象 A 持有对 B 的强引用,则存在有向边 A → B;
  • GC Roots 构成初始顶点集 R ⊆ V,包括栈帧局部变量、静态字段、JNI 引用等;
  • “活对象”即从 R 出发、沿有向边可到达的所有顶点构成的子图 Glive ⊆ G。

因此,并发标记的目标,就是高效、一致地识别出 Glive 的全部顶点,且全程允许 mutator(业务线程)修改 E(即新增/断开引用)。

三色标记是图遍历的状态机抽象

ZGC 复用三色标记作为并发遍历的状态协议:

  • 白色顶点:尚未被任何 GC 线程访问,处于“未探索”状态;
  • 灰色顶点:已被访问,其邻接边(引用)尚未完全扫描,是“待扩展”状态;
  • 黑色顶点:自身及所有直接邻接顶点均已扫描完成,是“已收敛”状态。

该状态机天然支持并发:多个 GC 工作线程可同时从灰色集合中取顶点、将其邻接白顶点染灰、自身染黑,只要保证状态跃迁原子性(ZGC 依赖着色指针高位 + 原子 CAS 实现),就不会出现状态冲突或重复入队。

着色指针 + 读屏障实现硬件级协同去重

ZGC 不依赖全局队列或锁来协调线程,而是把“去重逻辑下沉到指针层面”:

  • 每个对象指针的高位(如 4 位)编码其标记状态(Marked0 / Marked1),该状态随对象本身存储在内存中,所有线程通过同一物理地址读取时看到一致视图;
  • 当 GC 线程尝试将某白色对象染灰时,执行原子 CAS:仅当指针当前为白色才成功写入灰色状态,失败即说明其他线程已处理——这是硬件级的“一次生效”保障;
  • 读屏障(Load Barrier)在业务线程解引用对象前插入检查:若发现目标对象处于“正在转移中”或“已标记但未重定位”,则触发即时重定位或转发,确保后续访问始终命中最新状态,避免因并发修改导致的路径分裂或跳过。

这种设计使“多个线程扫描同一对象”的概率趋近于零,不是靠调度规避,而是靠状态位+原子操作+屏障拦截,在 CPU 缓存一致性协议(如 MESI)支持下完成自然去重。

页面粒度与并行任务划分降低图结构干扰

ZGC 将堆划分为固定大小页面(如 2MB),每个页面作为并发标记的基本调度单元:

  • GC 工作线程按页面分配任务,每个页面内对象拓扑相对局部,减少跨页引用带来的缓存抖动;
  • 页面间无依赖,可完全并行处理,避免传统基于对象图深度优先遍历中的栈竞争和递归同步开销;
  • 即使 mutator 在标记中修改了跨页引用,读屏障会捕获该变更并通知标记线程补扫——这相当于在图动态演化中维持弱一致性遍历,而非强一致快照。

最终效果是:遍历覆盖完整可达子图,线程间无冗余扫描,无锁等待,停顿只发生在根集(GC Roots)扫描阶段,与图规模无关。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2949

3

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

2023.07.25

2208

9

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

2023.08.02

1180

5

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.09

1118

4

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

2023.09.05

1316

5

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2058

7

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

2023.09.20

3240

8

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

2023.09.22

14495

6

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

529

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习