文章目录

  • 1 三色标记流程
    • 1.1 初始标记
    • 1.2 并发标记
    • 1.3 重新标记
    • 1.4 清除阶段(Sweep)
    • 1.5 为什么初始标记和重新标记需要STW,而并发标记不需要?
  • 2 并发标记的写屏障
  • 3 多标问题
  • 4.漏标问题
    • 4.1 漏标的两个必要条件
    • 4.2 解决方案一:增量更新(CMS)
    • 4.3 解决方案二:原始快照(SATB,G1)
    • 4.4 为什么 G1 选择 SATB?
  • 5.面试回答模板

1 三色标记流程

三色标记算法是一种JVM中垃圾标记的算法,他可以减少JVM在GC过程中的STW时长,他是CMSG1等垃圾收集器中主要使用的标记算法

在出现三色标记算法之前,JVM中垃圾对象的标记主要采用可达性分析算法及引用计数法。但是这两种算法存在以下问题:

  • 1、循环引用问题,如果两个对象互相引用,就形成了一个环形结构,如果采用引用计数法的话,那么这两个对象将永远无法被回收。
  • 2、STW时间长,可达性分析的整个过程都需要STW,以避免对象的状态发生改变,这就导致GC停顿时长很长大大影响应用的整体性能。

为了解决上面这些问题,就引入了三色标记法.
三色标记法将对象分为三种状态:白色、灰色和黑色

  • 白色:该对象没有被标记过
  • 灰色: 该对象已经被标记过了,但该对象的引用对象还没标记完
  • 黑色: 该对象已经被标记过了,并且他的全部引用对象也都标记完了,

三色标记法的标记过程可以分为三个阶段: 初始标记(Initial Marking)并发标记 (Concurrent Marking)重新标记 (Remark)

1.1 初始标记

  • 目标:标记所有GC Roots 直接引用的对象
  • 操作:
    • 所有对象初始为 白色。
    • 从 GC Roots(如虚拟机栈引用、方法区静态属性、本地方法栈引用等)出发,将 直接引用的对象 标记为 灰色。
    • 初始标记阶段只扫描 GC Roots 的直接引用链,不深入遍历整个对象图。
  • 是否 STW:是(Stop The World)。
  • 特点:时间短,仅扫描根对象的直接引用。

1.2 并发标记

  • 目标:从灰色对象出发,遍历整个对象图,标记所有可达对象
  • 操作:
    • 从灰色集合中取出对象,将其标记为 黑色,并将其引用的白色对象标记为 灰色。
    • 重复上述过程,直到灰色集合为空。
    • 在此阶段,应用程序线程与 GC 线程并发执行,用户代码可能修改对象引用关系
  • 是否 STW:否(无需 Stop The World)。
  • 关键问题:
    • 并发修改的挑战:用户线程可能新增或断开引用,导致漏标或多标(如黑色对象新增引用白色对象)。
    • 解决方案:使用 写屏障(Write Barrier) 技术,拦截对象引用的修改操作,并更新标记状态。
      • 增量更新(Incremental Update):当黑色对象新增指向白色对象的引用时,记录该引用,后续重新扫描。
      • 删除写屏障(Destructive Write Barrier):当白色对象的引用被断开时,将其标记为灰色。
  • 耗时分析:
    • 最耗时的阶段,需遍历整个对象图。
    • 优势:通过并发执行,减少 STW 时间,提升系统响应性。

1.3 重新标记

  • 目标:修正并发标记阶段中因用户线程修改对象引用导致的漏标或误标
  • 操作:
    • 从灰色集合重新开始遍历对象图,修正标记状态。
    • 处理 未被并发标记阶段遍历到的对象(如新增的引用)。
  • 是否 STW:是(Stop The World)。
  • 特点:
    • 时间通常较短,因为只需修正少量错误

以上三个标记阶段中,初始标记和重新标记是需要STW的,而并发标记是不需要STW的。其中最耗时的其实就是并发标记的这个阶段,因为这个阶段需要遍历整个对象树,而三色标记把这个阶段做到了和应用线程并发执行,大大降低了GC的停顿时长

1.4 清除阶段(Sweep)

  • 目标:回收所有 白色对象(不可达对象)。
  • 操作:
    • 遍历堆内存,回收白色对象的内存空间。
    • 将黑色对象重置为白色,以便下次 GC 使用。
  • 是否 STW:否(部分垃圾收集器可并发执行)。

1.5 为什么初始标记和重新标记需要STW,而并发标记不需要?

在初始标记阶段,针对根 (GCRoot)直接引用的对象进行标记,这个过程也通常被叫做根扫描

为了防止在初始标记过程中根对象被修改,这个过程是STW的,虽然G1可以通过采用写屏障技术来获知对象是否发生了修改,但是因为大多数的GCRoot他并不是对象,所以无法被获知的,所以,这个阶段是需要进行STW的。

重新标记阶段,目的是修正并发标记阶段因应用程序继续运行而产生的任何变化(因为并发标记没有STW,所以会有变化)。此时,需要重新检查和更新那些在并发标记阶段可能发生变化的对象标记信息。

重新标记是清理前的最后一次标记,需要确保这个过程的准确性,所以需要做STW来保证。

总之,三个阶段,为了提升性能肯定是能不STW就不STW,而最后一个阶段一一重新标记因为是最终阶段,所以需要STW来确保准确性。而第一个阶段一初始标记,因为无法感知到GCRoot的变化,所以需要做STW来确保这个阶段的准确性。

2 并发标记的写屏障

并发标记过程中,应用程序线程可能会修改对象图,因此垃圾回收器需要使用写屏障 (Write Barrier) 技术来保证并发标记的正确性

写屏障是一种在对象引用被修改时,将其新的引用信息记录在特殊数据结构中的机制。在三色标记法中,写屏障技术被用于记录对象的标记状态,并且只对未被标记过的对象进行标记。

当应用程序线程修改了一个对象的引用时,写屏障会记录该对象的新标记状态。如果该对象未被标记过,那么它会被标记为灰色,以便在垃圾回收器的下一次遍历中进行标记。如果该对象已经被标记为可达对象,那么写屏障不会对该对象进行任何操作。

通过使用写屏障技术,可以使得三色标记法过程中标记更加准确。然而,尽管写屏障对于维护垃圾收集器的准确性至关重要,它们仍然存在一些局限性,

  • 1.性能开销.: 写屏障会引入额外的性能开销,因为每次对象引用更新时都需要执行额外的代码。这种开销可能导致系统性能下降,尤其是在高度并发的场景中
  • 2.并发修改的挑战: 在高度并发的应用中,对象的引用可能会频繁变化。写屏障需要在每次引用变化时及时更新信息,但在极端并发条件下,可能难以捕捉到所有的变化。
  • 3.保守策略导致的多标: 为了避免误删除有效对象,一些垃圾收集器可能采取保守策略,在存在不确定性时选择保留对象。这可能导致实际上已经不再使用的对象被错误地标记为存活。
  • 4.优化策略的双刃剑: 为了减轻性能开销,某些垃圾收集器可能采用优化策略,例如只在特定条件下激活写屏障。这种优化有可能导致某些引用更新被错过,影响标记的准确性。

3 多标问题

所谓多标,其实就是这个对象原本应该被回收掉的白色对象,但是被错误的标记成了黑色的存活对象。从而导致这个对象没有被GC回收掉。

这个一般发生在并发标记过程中,该对象还是有引用的,但是在过程中,应用程序执行过程中把他的引用关系删除了,导致他变成了一个垃圾对象,

多标的话,会产生浮动垃圾,这个问题一般都不太需要解决,因为这种垃圾一般都不会太多,另外在下一次GC的时候也都能被回收掉。

4.漏标问题

4.1 漏标的两个必要条件

  • 黑色对象新增引用白色对象(条件①)
    • 黑色对象(已标记为存活)新增指向白色对象(未被标记)的引用,导致白色对象被漏标。
  • 灰色对象删除对白色对象的引用(条件②)
    • 灰色对象(正在扫描)在扫描完成前断开对白色对象的引用,导致白色对象失去所有路径连接。

漏标必须同时满足这两个条件才会发生。因此,解决方案只需要 破坏其中一个条件 即可。

4.2 解决方案一:增量更新(CMS)

目标:破坏条件①(黑色对象新增引用白色对象)

  • 核心思想:如果黑色对象新增了对白色对象的引用,就 将黑色对象重新标记为灰色,并在后续重新扫描其引用链。这样白色对象会被标记为灰色,避免漏标。
  • 具体操作:
    • 写屏障:当黑色对象新增引用白色对象时,记录该引用关系。
    • 重新标记阶段:以这些新增的引用为起点,重新扫描黑色对象的引用链。
  • 类比:
    • 假设你在打扫房间(GC),已经标记某个抽屉(黑色对象)里的物品为“必须保留”。此时家人往抽屉里放了新东西(白色对象)。
    • 增量更新就像家人给你留个便条:“这个抽屉有新增物品,请重新检查”,你就会回去重新扫描抽屉,确保新物品不被遗漏。
  • 优点:
    • 不产生浮动垃圾(所有被引用的对象都会被正确标记)。
  • 缺点:
    • 需要重新扫描整个引用链,耗时较长(尤其是引用链复杂时)

4.3 解决方案二:原始快照(SATB,G1)

目标:破坏条件②(灰色对象删除对白色对象的引用)

  • 核心思想:在 GC 开始时,记录所有存活对象的状态(快照)。即使后续引用被删除,也以快照为准,确保白色对象不会被漏标。
  • 具体操作:
    • 写屏障:当灰色对象删除对白色对象的引用时,记录该白色对象为“快照中的存活对象”。
    • 重新标记阶段:以这些白色对象为起点,重新扫描它们的引用链。

4.4 为什么 G1 选择 SATB?

  • 性能优先:
  • SATB 只需扫描被删除引用的对象(通过 RSet 和 Card Table 快速定位),而增量更新需要重新扫描整个引用链。
  • 对于大堆场景(如 G1 的 Region 划分),SATB 的效率优势更明显。
  • 浮动垃圾容忍度高:
    • 浮动垃圾只是延迟到下一轮 GC 清理,不会影响当前 GC 的准确性。相比而言,增量更新的耗时可能影响系统响应时间。
  • 与 Region 结构适配:
    • G1 的 Region 结构天然支持 RSet(记录跨 Region 引用),方便快速定位被删除引用的对象。

5.面试回答模板

垃圾回收机制需要分为两个步骤进行,第一标记出哪些是需要回收的垃圾,第二根据相应的清除机制如:标记复制、标记清除、标记整理等,而三色标记就是为了避免标记垃圾时STW的问题,三色标记将对象分为三种颜色,白色、灰色、黑色、其中白色表示未被引用的对象也是需要删除的对象,灰色表示对象已经被标记,但其引用还未标记,黑色表示对象及其引用都已经被标记,整个标记过程主要分为三个阶段:初始标记、并发标记和重新标记,初始标记主要是从GC Root出发,直接将引用对象标记为灰色,此时会引起stw,但耗时较短,并发标记从灰色对象出发,遍历整个对象图,耗时最长,但是不会引起stw,会和工作线程并发执行,但是并发执行期间会产生一些浮动的垃圾,这些浮动垃圾需要依靠重新标记去修正,此时也会引起stw,防止产生更多的浮动垃圾,并发标记阶段会通过写屏障来保证并发标记的准确性,针对漏标的问题一般可以通过增量更新或快照的方式去解决

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/95452.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95452.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/95452.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

反射的详解

目录一、反射1.JDK,JRE,JVM的关系2.什么是反射3. 三种获取Class对象(类的字节码)的方式4.Class常用方法5. 获取类的构造器6.反射获取成员变量&使用7.反射获取成员方法8.综合例子一、反射 1.JDK,JRE,JVM的关系 三者是Java运行环境的核心组成部分,从包含关系上看…

Grafana Tempo日志跟踪平台

以下是Grafana Tempo文档的总结(基于最新版文档内容): 核心概念 分布式追踪系统:Tempo是开源的分布式追踪后端,专注于高吞吐量、低成本存储和与现有监控生态的深度集成 架构组成: Distributor&#xff1a…

Qt基本控件

Qt 的基本控件是构建用户界面的基础,涵盖了按钮、输入框、容器、显示组件等,适用于传统 Widget 开发(基于 QWidget)。以下是常用基本控件的分类总结:一、按钮类控件用于触发交互操作,如提交、取消、选择等。…

用Voe3做AI流量视频,条条10W+(附提示词+白嫖方法)

最近 AI 视频的风从大洋彼岸吹过来,Voe3 的技术升级,诞生了很多很有意思的玩法。 比如:AI ASMR 切水果解压视频,卡皮巴拉旅行博主、雪怪 AI Vlog,动物奥运会、第一人称视角穿越古战场直播。 这些视频的流量很好&…

嵌入式学习的第四十八天-中断+OCP原则

一、GIC通用中断控制器 1.GIC通用中断控制器 GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器,GIC接收众多外部中断,然后对其进行处理,最终通过VFIQ、VIRQ、FIQ 和 IRQ给内核;这四个 信号的含义如下: VFIQ:虚拟…

一周学会Matplotlib3 Python 数据可视化-绘制条形图(Bar)

锋哥原创的Matplotlib3 Python数据可视化视频教程: 2026版 Matplotlib3 Python 数据可视化 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 课程介绍 本课程讲解利用python进行数据可视化 科研绘图-Matplotlib,学习Matplotlib图形参数基本设置&…

阿里研发效能提升【60篇】

阿里研发效能提升【60篇】 1、建立研发效能提升的系统框架 01、《从DevOps到BizDevOps,研发效能提升的系统方法》 视频版:2021云栖大会云效BizDevOps论坛 文字版:深度 | 从DevOps到BizDevOps, 研发效能提升的系统方法-阿里云开发者社区 …

面试实战 问题二十六 JDK 1.8 核心新特性详解

JDK 1.8 核心新特性详解 1. Lambda表达式 最核心的特性,简化函数式编程,语法:(参数) -> 表达式 // 传统方式 Runnable r1 new Runnable() {Overridepublic void run() {System.out.println("传统方式");} };// Lambda方式 Runn…

STM32H743开发周记问题汇总(串口通讯集中)

溢出错误出现的串口接收过程中,中断接收在溢出后无法进入,需要重点考虑溢出问题,以下是溢出恢复代码波特率115200 优先级0-1 高于定时器 初步诊断是数据流导致的接收溢出问题/*** brief 检查并清除UART溢出错误(带状态…

Linux中FTP配置与vsftpd服务部署指南

Linux中FTP配置与vsftpd服务部署指南 一、FTP 核心概念 1、基本定义 文件传输协议(FTP),基于 C/S模式 工作。控制端口:21(身份验证与指令传输) 数据端口:20(主动模式数据传输&#x…

Web UI自动化测试的早期介入?

在传统研发流程中,Web UI自动化测试常被视为“后期活动”——必须等待前端界面完全稳定才能启动。这种滞后导致自动化测试难以覆盖早期迭代,形成“开发等测试、测试等稳定”的恶性循环。本文将系统破解这一困局,提供一套从需求阶段介入、持续…

基于学科竞赛的高职计算机网络教学解决方案

一、引言《关于深化产教融合的若干意见》明确提出 “推行面向企业真实生产环境的任务培养模式”,为我国职业教育发展指明了产教深度融合的方向。在数字经济时代,计算机网络技术正以前所未有的速度迭代更新,产业界对具备前沿技术应用能力和实践…

猿大师中间件:Chrome网页内嵌PhotoShop微信桌面应用程序

随着桌面应用程序集成到网页的需求不断增长,尤其在Chrome浏览器缺乏原生调用EXE功能的情况下,传统网页内嵌解决方案面临失效挑战,猿大师中间件因此发展成为当前主流方案。 2025年猿大师发布了EXE、OCX、COM三个通用组件,自此猿大…

EF (Entity Framework) vs LINQ to SQL vs SqlSugar 全方位对比分析

文章目录1. 概述与背景介绍1.1 Entity Framework (EF)1.2 LINQ to SQL1.3 SqlSugar2. 架构设计对比2.1 EF架构设计2.2 LINQ to SQL架构2.3 SqlSugar架构3. 性能对比3.1 基准测试数据3.2 性能分析3.3 内存使用4. 功能特性对比4.1 数据库支持4.2 主要功能对比4.3 高级特性5. 开发…

MySQL 多表联查与内外连接详解

多表联查是关系型数据库的核心操作,用于从多个表中关联数据。MySQL 支持多种连接方式,最常用的是内连接和外连接(左/右/全外连接)。一、多表联查基础语法 SELECT 列列表 FROM 表1 [连接类型] JOIN 表2 ON 连接条件 [连接类型] JOI…

《网络爬虫》

网络爬虫,是一种自动化程序,用于抓取互联网上的数据。它们通过模拟浏览器行为,抓取网页内容并提取有用信息。爬虫广泛应用于数据采集、搜索引擎索引、竞争对手分析等领域。爬虫的工作流程:请求目标网页:爬虫首先发送 H…

openpnp - 顶部相机环形灯光DIY

文章目录openpnp - 顶部相机环形灯光DIY概述笔记ENDopenpnp - 顶部相机环形灯光DIY 概述 底部相机灯光用环形灯(用钣金折弯成一个10mm高的矩形盒子)是可以的。因为吸嘴落到Z方向和PCB平齐时,用COB灯带装在一个矩形盒子中正好能照射到吸嘴尖端高度附近。 顶部相机…

[AI React Web] E2B沙箱 | WebGPU | 组件树 | 智能重构 | 架构异味检测

第三章:E2B沙箱交互 在前两章中,我们掌握了对话状态管理和AI代码生成管道的运作原理。 但生成代码如何真正运行?这正是E2B沙箱交互的核心价值。 架构定位 E2B沙箱是专为open-lovable打造的虚拟计算环境,具备以下核心能力&…

Redis宝典

Redis是什么 Redis是开源的,使用C语言编写的,支持网络交互,可基于内存也可持久化到本地磁盘的Key-Value数据库。 优点: 因为Redis是基于内存的,所以数据的读取速度很快Redis支持多种数据结构,包括字符串Str…

MyBatis-Plus 分页失效问题解析:@Param 注解的影响与解决方案

引言在 Spring Boot MyBatis-Plus 的开发中,分页查询是常见的需求。然而,有时我们会遇到分页失效的问题,尤其是在方法参数上添加 Param 注解后。本文将通过一个实际案例,分析 Param 注解如何影响 MyBatis-Plus 的分页机制&#x…