讲师中心 微信公众号
AI工具推荐 视频效率加速

详解Java中的三色标记算法_并发扫描过程中的漏标问题与解决方案

酷雪大大_1633

酷雪大大_1633

发布时间:2026-02-20 02:15:14

|

585人浏览过

|

来源于php中文网

原创

三色标记算法漏标的根本原因是写屏障缺失或覆盖不全。并发标记时,若对象引用更新未经写屏障捕获(如JIT优化、Unsafe操作、final字段构造器外赋值),已标记为黑色的对象引用新对象而灰色对象尚未扫描到,就会导致本该存活的对象被误标为白色。

详解java中的三色标记算法_并发扫描过程中的漏标问题与解决方案

三色标记算法漏标的根本原因是什么

三色标记本身是安全的,但并发扫描时,应用线程和 GC 线程同时修改对象图,就可能让本该存活的对象被误标为白色。关键不在“三色”,而在「写屏障缺失」或「屏障覆盖不全」。

  • 漏标只发生在:一个对象 A 已被标记为黑色(扫描完成),它引用了新创建的对象 B,而 B 又被另一个灰色对象 C 引用 —— 但 C 还没扫描到 B,且 A 不再被重新扫描
  • 典型触发场景:obj.field = new Object() 发生在并发标记阶段,且旧引用被覆盖前未通知 GC
  • HotSpot 中,CMS 使用增量更新(IU)写屏障,G1/ZGC 使用原始快照(SATB)写屏障,策略不同,但目标一致:捕获“即将丢失”的引用

如何验证你的 JVM 是否真的在用 SATB 或 IU

别猜,看 JVM 启动日志或运行时参数。不同垃圾收集器默认策略固定,强行改写屏障类型通常无效甚至报错。

  • G1 默认启用 SATB:启动时若看到 Using G1 和 SATB barriers enabled 就对了
  • CMS 默认用 IU:日志中会出现 ConcurrentMarkSweepGeneration + Incremental Update
  • ZGC / Shenandoah:不暴露传统写屏障开关,它们通过读屏障+转发指针实现,-XX:+UnlockExperimentalVMOptions 下也无对应 -XX:+UseXXXBarrier 参数
  • 错误尝试:-XX:+UseCondCardMark 是优化卡表写入的,并非切换三色策略,开了也没用

G1 的 SATB 写屏障为什么有时仍会漏标

SATB 本质是“记录引用被覆盖前的旧值”,但它依赖一个前提:所有赋值操作都必须经过屏障。而某些场景下,JVM 会绕过屏障。

Java调试
Java调试

通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。 术语注解 JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议) remote JVM:远程 Java 虚拟机 step through code:代码单步调试(步入 / 步过 / 步出调试) inspect variables:变量查看 / 变量检视 stac

下载
  • JIT 编译后内联或消除冗余写操作,导致 obj.field = null 这类“清空引用”没走屏障
  • 使用 Unsafe 直接内存操作(如 Unsafe.putObject)完全跳过 Java 层写屏障
  • final 字段在构造器中初始化时,JVM 可能省略屏障(JMM 允许,但 GC 无法感知)
  • 实操建议:避免在并发标记高峰期用 Unsafe 修改对象图;final 字段尽量在构造器里一次性设完,别后续补

写屏障开销大不大?能不能关掉

不能关,也不该关。写屏障不是“可选性能开关”,而是并发可达性分析的必要基础设施。

立即学习“Java免费学习笔记(深入)”;

  • 每次对象字段赋值都多一次内存写(SATB 是写入缓冲区,IU 是更新卡表),实测增加约 5%~10% 的 mutator 开销
  • 但相比漏标导致的 Full GC,这点开销微不足道 —— 一次漏标可能让整个堆重扫,停顿从几毫秒飙到几百毫秒
  • 常见误解:-XX:-UseCondCardMark 能关屏障?不能,它只是控制是否用条件判断优化卡表写入,底层屏障逻辑仍在
  • 真正影响性能的是屏障实现质量:ZGC 把屏障逻辑压进 load 指令,G1 在 store 指令后插汇编 stub,后者更容易受 CPU 流水线干扰

三色标记的并发安全性,不取决于颜色怎么分,而取决于每一次引用变更是否被可靠捕获。很多人盯着算法图解看半天,却忘了翻一翻自己代码里那行 unsafe.putObject。

热门AI工具

更多
Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

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

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

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6487

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2708

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4578

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

6596

2023.08.14

Tailwind CSS 如何制作导航栏和卡片
Tailwind CSS 如何制作导航栏和卡片

用 Tailwind CSS 制作导航栏和卡片,可先搭建语义化结构,再组合 Flex、Grid、间距、圆角与阴影类。这里整理横向导航、移动端菜单、卡片网格及悬停效果的相关文章,帮助你把常见页面组件做得清晰且适配不同屏幕。

0

2026.11.03

Tailwind CSS 响应式布局怎么写
Tailwind CSS 响应式布局怎么写

Tailwind CSS 响应式布局通常从移动端样式写起,再用 sm、md、lg 等前缀调整不同屏幕宽度下的网格、间距和导航。本专题整理断点配置、Grid 与 Flex 自适应布局及常见溢出问题,帮助你逐步完成多设备适配。

0

2026.11.03

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn