文章目录

  • 为什么要使用三色标记法?
  • 三色标记法中的三色
  • 三色标记的漏标问题
  • 如何解决漏标问题?
    • CMS 增量更新(Incremental Update)
    • G1 原始快照(Snapshot At The Beginning, SATB)

三色标记法是JVM中用来标记对象是否为垃圾的一种方法,主要是针对CMS、G1等垃圾收集器使用的,这类收集器都有一个垃圾回收线程与用户线程同时执行的并发过程,这是一般标记清除算法不能支持的。

为什么要使用三色标记法?

三色标记法就是为了使垃圾扫描阶段能够与用户线程并发执行而产生的,因为传统的标记清除算法,必须要暂停所有用户线程。

传统的标记清除算法下,只有两个状态位0、1,比如0:表示未标识,1:表示对象可达,一次扫描后结束清除所有状态为0的,然后再把状态为1的重置为0。

但是如果与用户线程同时执行就不能这样玩了,因为一旦同时执行就有可能在一条链未全部扫描完的情况下,用户线程改变了这条链上的引用关系,比如现在有一条引用链:A—>B—>C—>D,当扫描到C时,A和B都被标识为1,此时C到D的引用关系被删除,那么D对象就不能确定是否为垃圾对象,因为有可能D又被用户线程设置为其他对象的引用了,那么为了D不被误删,只能让D的标识也为1,但是如果D就是没有被其他对象引用了,那么D就逃过了这次垃圾收集的过程,这就会造成大量的浮动垃圾。

当然肯定也不能设置为0,因为0在未扫描之前虽然表示的是未标记对象,但是在扫描开始后就表示垃圾对象了。

所以上述问题很明显就是缺少了一个表示中间状态的过程,由于线程同时进行,所以引用链上的对象并不是简单的可达与不可达的关系,而是会有一个扫描过程中的状态,所以就出现了三色标记法。

三色标记法中的三色

白色:表示对象尚未被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段,所有的对象都是 白色的,若在分析结束的阶段,仍然是白色的对象,即代表不可达。

灰色:表示对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用还没有被扫描过,也就是整个引用链还未全部扫完。

黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色的对象代表已经扫描过,它是安全存活的,如果有其他对象引用指向了黑色对象,无须重新扫描一遍。黑色对象不可能直接(不经过灰色对象)指向某个白色对象。

初始阶段:全部为白色

A对象扫描完成后变为黑色,B对象正在扫描则标识为灰色,剩余的白色对象标识还未被扫描。

最终按照可达性分析算法一轮扫描下来结果如下

最终白色对象E即为垃圾对象。

主要就是利用三个集合,分别来存放三种颜色的对象,开始扫描时把被扫描的白色对象从白色集合中移动到灰色集合中,灰色对象扫描完成后,又被移动到黑色对象集合中,最终完成所有初始标记时识别到的GCRoot引用链路径后,余下的白色集合中的对象即为垃圾对象。

三色标记的漏标问题

三色标记的思想非常简单,但仔细分析一下就会发现其中的问题,如果把一个白色对象的引用设置到一个黑色的对象上,那么这个白色对象就会被错误的认为是一个垃圾对象,因为黑色对象表示的是这个对象已经完成了扫描且这个对象的所有引用都已经扫描过。

第一次标记时,关系如下:


用户线程修改了引用关系如下:

此时接着扫描E对象,发现E对象之后没有引用关系了,把E对象设置为黑色,垃圾收集器认为两条引用链上的对象全部扫描完毕,但是F对象却被遗漏了。

Wilson于1994年在理论上证明了,当且仅当以下两个条件同时满足时,会产生“对象消失”的问 题,即原本应该是黑色的对象被误标为白色:

1、赋值器插入了一条或多条从黑色对象到白色对象的新引用;

2、赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。

如何解决漏标问题?

既然问题的产生需要同时满足上述两个条件,那么要解决就只需破坏其中一种即可,CMS和G1恰好分别利用其中一种条件来解决。

CMS 增量更新(Incremental Update)

增量更新要破坏的是第一个条件,当黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。这可以简化理解为,黑色对象一旦新插入了指向白色对象的引用之后,它就变回灰色对象 了。

C对象被修改为灰色,那么就会沿着灰色对象继续扫描,最终会扫描到F对象。

G1 原始快照(Snapshot At The Beginning, SATB)

原始快照要破坏的是第二个条件,当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描 一次。这也可以简化理解为,无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照来 进行搜索。

第一、二两条链扫描完成后,多出了第三条引用链,从之前的灰对象E开始,指向F对象,这样F对象就不会被清理掉了。

使用这种方式会有一个问题,假设引用关系如下:


之后引用关系被改变

E到F的引用没有了,F也没有再被其他对象引用,但是由于E对象为灰色对象,所以为了避免漏标,E对象最终还是会有一条到F的引用关系,这就是浮动垃圾问题,F对象会逃过本次的垃圾扫描,等待下次再被清理,但这总比漏标要好的多。

对比文章一开始提到的标记清除方法下产生的浮动垃圾问题,这种情况要少很多,因为只有在改变灰色对象时才需要记录,而如果用标记清除那么只要在垃圾回收期间改变了对象的关系都必须定义为非垃圾对象。

详细图解JVM三色标记法相关推荐

  1. 双/三色标记法的垃圾回收(GC)原理解析和缺陷解决方案(Go,Lua以及jvm的CMS和G1垃圾回收器中使用的回收算法)

    标记-清除算法 go和lua虚拟机以及jvm的CMS和G1垃圾回收器的回收算法的思想均来自于标记-清除算法(Mark-Sweep),它们的gc有重要的两部分: 1.从根节点遍历所有对象,如果可达到,则 ...

  2. 【JVM】三色标记法与读写屏障

    1.概述 首先:CMS和G1都使用了三色标记法 关于垃圾回收算法,基本就是那么几种:标记-清除.标记-复制.标记-整理.在此基础上可以增加分代(新生代/老年代),每代采取不同的回收算法,以提高整体的分 ...

  3. JVM垃圾回收——三色标记法

    目录 一.什么是三色标记 二.三色标记的过程 三.三色标记的缺点 四.垃圾回收机如何弥补三色标记的缺点 在CMS.G1这种并发的垃圾收集器收集对象时,假如一个对象A被GC线程标记为不可达对象,但是用户 ...

  4. 【JVM】三色标记法

    原因 在CMS等并发收集器,并发标记的过程中需要对对象进行标记,用于区别对象.防止多标,漏标等情况. 三色标记 三色标记法就是指将GC roots可达性算法分析遍历对象过程中将各个对象,按照" ...

  5. 你对JVM三色标记的理解嘛?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 三色标记法是一种 ...

  6. 说说关于JVM三色标记算法

    本文来说下关于JVM三色标记算法 文章目录 概述 三色标记算法思想 算法流程 三色标记存在问题 解决办法 CMS回顾 CMS解决办法:增量更新 CMS另两个致命缺陷 G1回顾 G1前置知识 Card ...

  7. JVM 三色标记 增量更新 原始快照

    2.1 基本算法 要找出存活对象,根据可达性分析,从GC Roots开始进行遍历访问,可达的则为存活对象: 最终结果:A/D/E/F/G 可达 我们把遍历对象图过程中遇到的对象,按"是否访问 ...

  8. JVM三色标记与读写屏障

    前言 本文主要讲解三色标记具体工作原理,多标导致的浮动垃圾.漏标的处理方案(读写屏障)等. 基本概念    JVM 中的垃圾回收是基于 标记-复制.标记-清除和标记-整理三种模式的,那么其中最重要的其 ...

  9. golang 垃圾回收、三色标记法、写屏障

    垃圾回收简称 GC,就是对程序中不再使用的内存资源进行自动回收释放的操作. 常见的垃圾回收算法 引用计数:每个对象维护一个 引用计数,当对象被创建或被其他对象引用时,计数 +1:如果引用该对象的对象被 ...

最新文章

  1. 缓存雪崩缓存击穿缓存穿透的本质
  2. TypeError: __init__() got an unexpected keyword argument ‘ratio‘
  3. Linux环境安装python3.6(APT方式)
  4. mysql中的主从复制slave-skip-errors参数使用方法
  5. 【原创】项目管理得失经验总结
  6. go int 最大值_Dig101 - Go之灵活的slice
  7. linux oracle bin目录在哪,linux 安装软件装完后在哪个目录
  8. VS2012错误之 warning LNK4075: 忽略“/EDITANDCONTINUE”(由于“/SAFESEH”规范)
  9. ubuntu install wiznote
  10. D-Link 智能家居新品将登陆苹果中国官网
  11. C语言之字符串(草稿)
  12. 英语绕口令大全 练习你的口语
  13. Elasticsearch生产集群健康状况为yellow原因分析和解决方案
  14. openresty 与 java RSA加解密
  15. MLX90640开发笔记(六)红外图像伪彩色编码
  16. 通讯录的思路与实现(C语言)
  17. 用逻辑回归实现鸢尾花数据集分类(1)
  18. send/sendto和recv/recvfrom各自的区别
  19. vue全家桶-组件内部应用守卫简洁版-防止输入框未保存的数据丢失
  20. Android中级——色彩处理和图像处理

热门文章

  1. 基于VBS的恶搞/表白程序
  2. mock 数据常用的工具网站
  3. 大型智慧灌区信息化管理系统云平台 智慧灌区信息化管理系统解决方案
  4. 编程规则 - 1 概述 -- 帮助你成长为优秀的程序员 杰出的软件工程师、设计师、分析师和架构师
  5. java 变量过期实现
  6. thinkpad硬件测试软件,Lenovo Diagnostics Windows(联想硬件诊断工具)
  7. System.Diagnostics 记录
  8. 下一代互联网实验:IPv6静态路由和路由汇总 IPv6 to IPv4 隧道 IPv6 NAT-PT 配置
  9. 2012年MacBook更换SSD固态硬盘和16G内存条
  10. Android手机AP模式下本机IP