JVM调优重新标记-三色标记法

前言

介绍三色标记法前,先了解G1回收器的两个概念:

CSet:也叫Collection Set,这个set中装着需要被回收的region。

RSet:也叫Remembered Set,每个region都有一个RSet,记录着有哪些region中有引用指向本

三色标记法

既然是三色标记法,顾名思义,就是用三种颜色来标记内存中的对象,这三种颜色表示不同的意义。

下面就是内存中的对象可能出现的三种颜色,以及它们表示的意义:

黑色:对象本身与其成员变量均已标记完成。
灰色:对象本身被标记了,但是它的成员变量还没有被标记完成
白色:未被标记的对象。

下面用张图直观的表示一下:
在这里插入图片描述
上面这张图中,B和C都是A的成员变量,D是B的成员变量。

由于A和C的本身以及它们的成员变量都被标记过了,所以它们自己就被标记为黑色。

而由于D是未被标记的白色,B只能是被部分标记的灰色。

用这种三色标记法,就可以保证,遍历完对象树之后,所有被标上颜色的对象,都是存活对象。

但是三色标记法也有其问题所在。

三色标记法的问题与解决办法

三色标记法就发生在CMS和G1的Mixed GC的并发标记阶段。

所以三色标记法没法解决引用关系发生改变的情况。

比如漏标问题,我们继续拿上面的图举例子。

如果发生了B对D的引用转移到了A中,就会成为下面这种情况。

在这里插入图片描述

由于A的新成员变量D是未被标记的白色,而理应是灰色的A已经被标成了黑色,这就会导致整个三色标记法规则的崩溃。

为了解决三色标记法的这种问题,CMS与Mixed GC选择了下面这两种不同的方式:

incremental update

增加了新引用的对象会被重新标记为灰色。

重新标记阶段对这个对象重新进行扫描。

拿上面的例子来说,如果A新增加了一个指向D的引用,那么就把A重新标记为灰色,然后等重新标记阶段对A的所有引用(A->B、A->C、A->D)进行扫描。

这是CMS采用的解决方案。问题就在于,这个解决方法的效率并不高,仅仅由于新增了一个新的引用,就要把该对象所有的引用都扫描一遍。

因此提出了下面这种解决方案。

SATB

全称为Snapshot At The Beginning。

这个方法有三个步骤:

1、在开始标记的时候,会生成一个所有对象的快照图。
2、在并发标记的过程中,如果发生了引用消失的情况,就将这个引用存到一个堆栈中。
3、在重新标记阶段,会对这个堆栈中的所有引用进行扫描。

这种方法与之前提到过的RSet浑然天成。

在重新标记阶段,只需要扫描消失引用所指向的对象的RSet就能确定,这个对象有没有被别的引用指向了。

而G1中的Mixed GC就采用了这种方法来进行标记。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值