三色标记算法过程及原理(Tri-color marking)

这篇具有很好参考价值的文章主要介绍了三色标记算法过程及原理(Tri-color marking)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.三色标记算法是什么

1.1 什么是三色

白色

灰色

黑色

2.三色标记算法的过程

3.三色标记算法的实现原理

3.1 三色集合

白色集合

灰色集合

黑色集合

3.2 三色标记算法实现

3.3 三色标记算法提炼

4.三色标记算法因为什么而出现

5.三色标记算法的漏洞

5.1 多标

5.1.1多标怎么发生的呢?

5.1.2多标问题如何解决?

5.2 漏标

5.2.1漏标是怎么发生的呢?

5.2.2漏标问题如何解决?

5.2.2.1 增量更新方案

5.2.2.2 原始快照方案

6.三色标记使用场景

6.1 三色标记在垃圾收集器CMS中使用

6.2 三色标记在垃圾收集器G1中使用


1.三色标记算法是什么

        三色标记算法是一种常见的垃圾收集的标记算法,属于根可达算法的一个分支,垃圾收集器CMS,G1在标记垃圾过程中就使用该算法。

        1.1 什么是三色

                三色指的是白色,灰色,黑色(white,gray,black)。抽象的理解,可以认为垃圾收集器在标记阶段将对象染成不同的颜色,根据不同的颜色做不同处理。那么三种染色的对象分别指什么呢?

        白色

                1- 在标记开始时,堆内存中的对象都是白色的。

                2- 在标记结束时,仍然是白色的对象,将会被视为已死的对象而被清除。

        灰色

                灰色是由白色标记成为灰色,表示该对象Obj是根可达对象(存活的对象,不会被清理),但Obj的所有引用的对象还没被垃圾收集器访问;灰色是一个过渡色,最终都会被标记为黑色。

        黑色

                黑色是由灰色标记成为黑色,表示该对象Obj以及Obj的所有下级引用对象都已经被垃圾收集器访问并标记,Obj不会被垃圾收集器再次访问以查看是否有引用对象;此时Obj是黑色(存活的对象,不会被清理),Obj的所有引用的对象被标记为灰色。

        总结

                三种颜色是递进的,最初所有对象颜色都是白色,对象Obj被根对象引用 当Obj被垃圾收集器访问后会被标记为灰色,当Obj的所有属性被访问标记(白色-->灰色)后Obj会被标记为黑色。

2.三色标记算法的过程

三色标记算法,JVM,算法,jvm,java,架构

1,堆中所有的对象都是白色的。


三色标记算法,JVM,算法,jvm,java,架构

2,根对象(GC Root set)引用的对象被垃圾收集器标记为灰色(图中A,F对象)


三色标记算法,JVM,算法,jvm,java,架构

3, 垃圾收集器扫描灰色对象A和对象F的引用对象,将所有A的引用对象标记为灰色(B,C,D对象),将A对象标记为黑色;灰色对象F无引用,直接将对象F标记为黑色。


三色标记算法,JVM,算法,jvm,java,架构

4,垃圾收集器扫描灰色对象B,C,D,发现B,C,D没有引用其他对象,将B,C,D标记为黑色。整个堆内存中没有灰色对象,A,B,C,D,F为黑色(存活对象),E,G,H为白色(已死对象),扫描标记完毕。


三色标记算法,JVM,算法,jvm,java,架构

5,对象E,G,H在三色标记完毕后还是白色,代表对象E,G,H是已死的对象,直接进行清除,回收已死对象所占内存。

3.三色标记算法的实现原理

        三色标记算法是由集合set实现的。三个集合分别为白,灰,黑集合;

        3.1 三色集合
        白色集合

                白色集合是已死对象的集合,集合内的对象在标记环节结束后将被清除回收。

        灰色集合

                灰色集合,灰色对象的集合,灰色的对象代表其被根可达的黑色对象引用,但是还没有扫描该灰色对象是否引用白色集合中的对象;因为灰色对象根可达,它不能被回收,而且所有灰色的对象在被垃圾回收器扫描后将被迁移到黑色集合。

        黑色集合

                黑色集合,黑色对象的集合,黑色对象代表其根可达,是存活的对象,不可以被回收;黑色对象没有引用指向白色对象,只能指向灰色对象

        3.2 三色标记算法实现

        在三色标记的过程,其集合内部的变化如下列图,右侧所示

        三色标记算法,JVM,算法,jvm,java,架构

        1,所有对象都是白色对象,放入白色集合。灰,黑集合此时为空


        三色标记算法,JVM,算法,jvm,java,架构

        2,被根对象引用的对象标记为灰色,并将灰色对象从白色集合中转移到灰色集合。


        三色标记算法,JVM,算法,jvm,java,架构

        3,垃圾收集器扫描灰色集合A,F对象,将A引用的对象B,C,D标记为灰色,转移到灰色集合中,A的所有引用对象都已扫描完毕,将A标记为黑色,转移到黑色集合中;F没有引用对象,标记为黑色,转移到黑色集合中。


        三色标记算法,JVM,算法,jvm,java,架构

        4,垃圾收集器扫描灰色集合B,C,D对象,B,C,D对象没有引用对象,标记为黑色,转移到黑色集合中。灰色队列已经空了,扫描完毕;黑色集合为根可达对象集合,其内部对象均为存活对象,白色集合为根不可达对象集合,其内部对象均为已死对象。


        三色标记算法,JVM,算法,jvm,java,架构

        5,清除白色集合内的已死对象E,G,H,实现内存回收。至此垃圾回收周期结束。

        3.3 三色标记算法提炼

                1,从灰色集合中取出一个对象Obj。

                2,将对象Obj引用的对象移动到灰色集合,以确保Obj以及Obj引用的对象不被回收。

                3,将对象Obj移动到黑色集合。

                4,重复以上三步,直到灰色集合为空。

                因为所有不能根可达的对象被加入到白色集合,而且对象只能够从白色集合转移到灰色集合,从灰色集合转移到黑色集合,所以不可能有黑色对象引用指向白色对象。

4.三色标记算法因为什么而出现

        三色标记出现前,垃圾回收使用的算法是标记-清除算法,该算法显著特点就是整个垃圾回收周期中,用户的所有线程都会停止,也就是STW(stop the world,整个用户线程完全停止运行),非常不友好。

        三色标记算法优化了标记-清除算法的STW,将一个相对大的STW分解成多个小的STW,做到了用户线程和垃圾回收的并发处理(这里并发也并非绝对并发,毕竟还存在少量的STW),减少了垃圾回收过程中STW的时间。

5.三色标记算法的漏洞

        三色标记算法因为存在并发标记过程,这会导致出现多标,漏标问题;

        什么是多标和漏标呢?

        多标漏标都有一个【标】字,就是标记的意思,抽象的说标记等同于染色,对象最初都是白色(未来要被清除的),一旦染色,无论白->灰或灰->黑,对象就是根可达对象(存活对象),染色就是让对象存活,同样标记就是让对象存活的意思。

        理解了【标】字代表让对象存活的意思,我们看多标,漏标就很好理解了,多标:多余标记,应该回收的对象,让它存活了,概括为让对象多存活了一会;漏标:遗漏/忘记标记,应该存活的对象,被回收了,概括为忘记让对象存活了

        5.1 多标

                多标:多余标记,应该回收的对象让它存活了,概括让对象多存活一会,多标会产生浮动垃圾。

                5.1.1多标怎么发生的呢?                        三色标记算法,JVM,算法,jvm,java,架构

                在并发标记阶段,垃圾收集器线程和用户线程同时运行,垃圾收集器线程在扫描完A,D对象之后,如果用户线程此时执行代码 D.E = null; 那么黑色对象D对灰色对象E的引用就会断开,灰色对象E已不是根可达对象,按说应该是白色,但是已经多余标记成了灰色,对象E,F,G最终会被标记成黑色,而不能被垃圾收集器清除,成为浮动垃圾。

                5.1.2多标问题如何解决?

                浮动垃圾对系统影响不大,无需干预,因为下次垃圾回收周期会把它们清除掉

        5.2 漏标

                漏标:遗漏/忘记标记,应该存活的对象,被回收了,概括为忘记让对象存活了

                漏标可是一个严重的问题!一个活生生的对象,突然就被回收啦,凡用该对象的地方都会报空指针异常

                5.2.1漏标是怎么发生的呢

三色标记算法,JVM,算法,jvm,java,架构

                在并发标记阶段,垃圾收集器线程和用户线程同时运行,垃圾收集器线程在扫描完对象E之后,如果用户线程此时执行代码 E.G = null; D.G = G;这时对象E和对象G之间的引用断开,对象D引用对象G。三色标记算法中黑色对象表明了其所有的引用的对象都已被扫描并标记为灰色,并且不会再次扫描黑色对象的下级引用,这样会导致一个结果:虽然对象G根可达,但是它不会被扫描和被标记为灰-黑色,标记环节结束时,会把对象G当做垃圾清除掉

                5.2.2漏标问题如何解决?

                漏标问题的发生必须满足两个充要条件:

                        1,至少有一个黑色对象新增了对白色对象的引用

                        2,所有灰色对象指向该白色对象的引用都断开了

                如上图所示,条件1,2均被满足,必然发生漏标问题。

                        1),黑色对象D新增了对白色对象G的引用        (满足条件1)

                        2),灰色对象E指向白色对象G的引用被断开了 (满足条件2)

                条件2要满足所有指向该白色对象G的引用都断开,因为只有一个灰色对象D引用白色对象G,只需要断开这一条引用即可满足条件2.

                因为必须满足两个充要条件,才会发生漏标的问题,所以反向推理,如果破坏任何一个条件,这个白色对象就不会被漏标

                5.2.2.1 增量更新方案

                        增量更新破坏了第一个条件:「至少有一个黑色对象新增了对白色对象的引用」,在并发标记阶段,黑色对象D指向了白色对象G,这时会把黑色对象D记录下来,在重新标记阶段,会把黑色对象D标记为灰色对象D,然后以灰色对象D为根节点,扫描整个引用链,白色对象G就会被依次标记为灰色、黑色,白色对象G漏标的问题就解决了。

                        增量更新的缺点:会重新扫描以黑色对象D为根节点的整个引用链,会浪费多一点时间。

                        CMS垃圾收集器使用增量更新方案

                5.2.2.2 原始快照方案

                        原始快照破坏了第二个条件:「所有灰色对象指向该白色对象的引用都断开了」,在并发标记阶段,灰色对象E断开了对白色对象G的引用,这是会把白色对象G记录下来,在最终标记阶段,会把白色对象G标记为灰色,然后以灰色对象G为根节点,扫描整个引用链,如此以来原来的白色对象G就会被依次标记为灰色、黑色,白色对象G漏标的问题就解决了。

                        原始快照的缺点:如果没有黑色对象指向白色对象,白色对象就变成了浮动垃圾,等下次GC回收

                        G1垃圾收集器使用原始快照方案。

6.三色标记使用场景

        6.1 三色标记在垃圾收集器CMS中使用

                1)初始标记(CMS initial mark),根节点直接引用的对象标记为灰色(短暂的STW)

                2)并发标记(CMS concurrent mark)扫描灰色对象引用的对象并标记为灰色,原灰色对象标记为黑色

                3)重新标记(CMS remark)增量更新方案矫正并发标记阶段的错误(短暂的STW)

                4)并发清除(CMS concurrent sweep)清除白色的对象,内存回收

                注:1)3)初始标记,重新标记都是短暂的STW,用户所有线程都停止,等待标记完成。

                2)4)阶段都是并发操作,用户线程和垃圾收集器线程同时运行,不会STW。

三色标记算法,JVM,算法,jvm,java,架构

        6.2 三色标记在垃圾收集器G1中使用

                1)·初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象

                2)·并发标记(Concurrent Marking):从GC Root开始对堆中对象进行可达性分析

                3)·最终标记(Final Marking):原始快照方案处理并发阶段结束后仍遗留SATB记录

                4)·筛选回收(Live Data Counting and Evacuation):根据用户期望的停顿时间来制定回收计划

                注:1)3)4)初始标记,最终标记,筛选回收都存在STW,用户线程都停止。

                2)阶段都是并发操作,用户线程和垃圾收集器线程同时运行,不会STW。

三色标记算法,JVM,算法,jvm,java,架构

参考:

        https://en.wikipedia.org/wiki/Tracing_garbage_collection#Tri-color_marking

        https://www.cnblogs.com/tyhA-nobody/p/17578936.html

书籍:深入理解Java虚拟机:JVM高级特性…佳实践(第3版)周志明文章来源地址https://www.toymoban.com/news/detail-842247.html

到了这里,关于三色标记算法过程及原理(Tri-color marking)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM的组件、自动垃圾回收的工作原理、分代垃圾回收过程、可用的垃圾回收器类型

    https://www.processon.com/diagraming/64c8aa11c07d99075d934311 https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html 年轻代是所有新对象被分配和老化的地方。当年轻代填满时,这会导致minor garbage collection,minor gc会回收掉很多的游离对象。游离的年轻代很快就被收集起来。一些幸存的

    2024年02月14日
    浏览(49)
  • JVM GC 算法原理概述

    对于JVM的垃圾收集(GC),这是一个作为Java开发者必须了解的内容,那么,我们需要去了解哪些内容呢,其实,GC主要是解决下面的三个问题: 哪些内存需要回收? 什么时候回收? 如何回收? 回答了这三个问题,也就对于GC算法的原理有了最基本的了解。 1 如何判定哪些内

    2024年02月03日
    浏览(42)
  • GC 三色标记算法(Go & Java版本)

    GC全称Garbage Collection,目前主流的垃圾回收算法有两类,分别是追踪式垃圾回收算法(Tracing garbage collection)和引用计数法( Reference counting )。 而三色标记法是属于追踪式垃圾回收算法的一种。追踪式算法的核心思想是判断一个对象是否可达,因为一旦这个对象不可达就可以

    2024年02月05日
    浏览(32)
  • 昨晚做梦面试官问我三色标记算法

    本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 目录 三色标记算法 增量更新 原始快照 某天,爪哇星球上,一个普通的房间,正在举行一场秘密的面试: 面试官:我们先从JVM基础开始问,了解三色标记

    2024年02月11日
    浏览(41)
  • 从原理聊JVM(一):染色标记和垃圾回收算法

    作者:京东科技 康志兴 • 方法区 属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。运行时常量池,属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用。 JDK1.8之前,Hotspot虚拟机对方法区的实现叫做永久

    2023年04月21日
    浏览(36)
  • 【Java虚拟机】JVM垃圾回收机制和常见回收算法原理

    1.垃圾回收机制 (1)什么是垃圾回收机制(Garbage Collection, 简称GC) 指自动管理动态分配的内存空间的机制,自动回收不再使用的内存,以避免内存泄漏和内存溢出的问题 最早是在1960年代提出的,程序员需要手动管理内存的分配和释放 这往往会导致内存泄漏和内存溢出等问

    2024年02月02日
    浏览(54)
  • 标记垃圾,有三种色彩:四千长文带你深入了解三色标记算法

    🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者 📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代 🌲文章所在专栏:JVM 🤔 我当前正在学习微服务领域、云原生领域、消息中间件等架构、原理知识 💬 向我询问任何您想要的

    2024年02月13日
    浏览(41)
  • 【jvm系列-09】垃圾回收底层原理和算法以及JProfiler的基本使用

    JVM系列整体栏目 内容 链接地址 【一】初识虚拟机与java虚拟机 https://blog.csdn.net/zhenghuishengq/article/details/129544460 【二】jvm的类加载子系统以及jclasslib的基本使用 https://blog.csdn.net/zhenghuishengq/article/details/129610963 【三】运行时私有区域之虚拟机栈、程序计数器、本地方法栈 https

    2023年04月22日
    浏览(76)
  • 深度学习之详解常见梯度算法(概念、公式、原理、算法实现过程)

    目录 前言 一、如何实现梯度下降? 二、梯度计算 三、常见的梯度公式及梯度算法 常见的梯度公式: 1.标量对向量的梯度: 2. 标量对矩阵的梯度: 3. 向量对标量的梯度: 常见梯度算法: 四、常见梯度算法实现  1、批量梯度下降算法实现函数 2、随机梯度下降算法实现函数

    2024年04月15日
    浏览(45)
  • 拓扑排序详解(包含算法原理图解、算法实现过程详解、算法例题变式全面讲解等)

    在图论中,如果一个有向图无法从某个顶点出发经过若干条边回到该点,则这个图是一个有向无环图(DAG图)。 如图所示。 对于一个有向图,若x点指向y点,则称x点为y点的入度。 对于一个有向图,若x点指向y点,则称y点为x点的出度。 队列是一种特殊的线性表,特殊之处在

    2024年02月07日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包