怎么通过 Garbage First (G1) 收集器的 SATB 算法理解并发标记阶段的写屏障逻辑

轻墨大大_1475

轻墨大大_1475

2026-04-16

963人浏览

原创

satb写屏障仅在对象字段被覆盖且旧引用指向老年代(或收集集)时触发,不处理读、分配、方法调用及数组赋值;其正确性依赖initial mark的stw以确保根集合完整,否则会导致漏标和浮动垃圾。

怎么通过 garbage first (g1) 收集器的 satb 算法理解并发标记阶段的写屏障逻辑

G1 的 SATB 写屏障只拦截特定赋值动作,不是所有写操作都触发,理解这点是读懂并发标记逻辑的前提。

什么赋值会触发 SATB 写屏障?

SATB 写屏障只在满足「对象字段被覆盖」且「旧引用指向老年代(或当前收集集)」时才生效。它不关心读、分配、方法调用,也不处理数组元素赋值(那是 card table 的事)。

  • oldObj.field = anotherOldObj → 触发:老-老引用,旧值需记录进 satb_mark_queue
  • oldObj.field = youngObj → 不触发:目标是年轻代,G1 不通过 SATB 管理跨代弱引用
  • youngObj.field = oldObj → 通常不触发:源对象在年轻代,即使赋值后形成跨代引用,也由 remembered set + card table 处理
  • array[i] = obj → 不触发:数组元素更新走的是 write barrier for card marking,和 SATB 无关

为什么必须配合 Initial Mark 的 STW?

因为 SATB 的“快照”本质是基于初始标记那一刻的根集合构建的。如果根没扫全,后续所有 SATB 记录的旧值就失去了锚点——你连“谁活过”都不知道,还记什么“谁被删了”?

  • 没有 STW 的 Initial Mark,satb_mark_queue 里压入的对象可能根本不在初始快照链上
  • 最终标记(Remark)阶段要处理的不只是队列残留,更是补全那些因根扫描不完整而漏掉的灰色起点
  • 一旦 Initial Mark 漏掉某个活跃线程栈里的局部变量,它所引用的老年代对象哪怕被 SATB 记录了旧值,也不会被真正标记为存活

并发标记期间 satb_mark_queue 积压意味着什么?

积压不是性能瓶颈本身,而是应用行为与 G1 标记节奏不匹配的信号:大量老年代对象字段被高频修改(比如缓存热更新、配置重载),导致写屏障持续压入旧引用,而并发标记线程来不及消费。

  • 积压超过阈值会触发额外的 STW 暂停(可通过 -XX:+PrintGCDetails -XX:+PrintGCApplicationConcurrentTime 观察到 “SATB queue overflow”)
  • 这不是 GC 参数调优能根治的问题,得看业务代码是否真有必要频繁覆盖老年代对象的引用字段
  • 积压严重时,G1 可能提前结束并发标记,转入 Remark,导致混合 GC 延迟或回收效率下降

真正容易被忽略的是:SATB 不保证“零浮动垃圾”,它只保证“初始快照中活着的对象不会被误收”。而那个快照的完整性,完全依赖 Initial Mark 阶段的 STW 质量——哪怕只漏一个根,整个并发标记的保守性就塌了一角。

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

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

下载

相关标签:

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

相关专题

更多
PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

2026.10.10

20

15

Kratos框架HTTP与gRPC服务开发教程
Kratos框架HTTP与gRPC服务开发教程

本专题围绕Kratos框架双协议服务开发,涵盖HTTP路由与处理器编写、参数获取、gRPC服务实现与客户端调用、metadata上下文传递、encoding编解码注册、统一响应封装、超时控制与流式响应实现方法。

2026.10.10

20

15

Kratos框架Protobuf接口定义与代码生成合集
Kratos框架Protobuf接口定义与代码生成合集

本专题讲解Kratos框架接口定义体系,涵盖proto编写规范、proto add/client/server生成命令、http注解路由、validate校验、OpenAPI文档生成、跨服务proto复用与兼容性设计。

2026.10.10

0

15

C++虚函数怎么定义和调用
C++虚函数怎么定义和调用

C++虚函数是实现运行时多态的重要机制。本专题从virtual关键字的基本用法入手,介绍基类与派生类之间的函数重写、基类指针调用派生类方法,以及动态绑定的执行过程,帮助初学者掌握虚函数的核心语法。

2026.10.10

20

26

C++类与对象的封装方法教程
C++类与对象的封装方法教程

C++封装是面向对象编程的核心特性之一,通过类将数据与操作数据的函数组织在一起,并利用访问权限控制外部访问。本专题介绍类的定义、成员变量、成员函数以及public、private和protected的使用方法,帮助初学者掌握封装的基本原理。

2026.10.10

0

32

C++构造函数定义与调用方法
C++构造函数定义与调用方法

C++构造函数用于初始化类对象,是面向对象编程的重要基础。本专题从构造函数的定义、声明和调用入手,介绍默认构造函数、带参数构造函数、拷贝构造函数及成员初始化列表,帮助初学者掌握对象创建与初始化的基本方法。

2026.10.10

20

16

Kratos框架零基础入门教程
Kratos框架零基础入门教程

本专题整理Kratos框架入门内容,涵盖Go环境准备、kratos CLI安装升级、new命令创建项目、目录结构分层说明、服务启动与双协议端口、依赖下载报错排查,帮助开发者快速跑通第一个Kratos框架微服务应用。

2026.10.10

20

15

C++条件判断语句怎么写
C++条件判断语句怎么写

C++条件判断是控制程序执行流程的重要基础。本专题介绍if、if-else、else if和switch等常见分支语句,结合条件表达式、比较运算符与代码示例,帮助初学者掌握不同场景下的判断逻辑。

2026.10.10

0

13

C++变量怎么声明和赋值
C++变量怎么声明和赋值

C++变量是编写程序和存储数据的基础。本专题围绕变量声明、定义、初始化、赋值和类型选择等内容展开,帮助初学者理解不同变量的用法,并掌握在实际代码中定义和使用变量的方法。

2026.10.10

20

20

热门下载

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

精品课程

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

共6课时 | 54.6万人学习

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

共89课时 | 133.4万人学习