三色标记
- 三色标记
- Incremental Update write barrier
- STAB(Snapshot-at-beginning)
三色标记过程
白
假设内存初始状态如下图,在标记前 白色为所有对象的默认状态 ,在标记完成后 白色对象则为垃圾数据需要清理
灰
将A 和 E 已经标记完成 但是还未标记A和E的引用 所以灰色代表对象本身已经标记 但未标记对象所引用的值
黑
A A1 A2 C D E 将自己以及自己本身引用的对象全部标记过 那么A A1 A2 C D E则为黑色
漏标问题
在并发标记的时候 会产生漏标问题如下图
在A2为灰色的时候 应用程序线程删除了A2-> C的引用
同时增加了 黑色D(黑色代表全部标记完成的对象)引用了白色C的对象
此时就会产生C漏标 因为D是黑色 标记线程认为D已经标记完成 而A2已经删除了C对象 这个时候C对象从A2已经不可达 故C漏标
incremental update write barrier(增量写屏障)
这里的屏障不是指JMM中的内存屏障 而是另外一中实现逻辑称之为屏障
增量写屏障
增量写屏障也是CMS垃圾回收器采用的方式,但是会产生浮动垃圾
具体的可以查看CMS浮动垃圾,主要原因是因为增量
,增量的意思就是记录在并发阶段记录引用增加的关系 这里主要说明漏标,浮动垃圾会在CMS中详细说明
在黑色对象需要访问白色对象的时候 也就是 黑色对象添加了白色对象引用的时候,会将本来为黑色对象的值变更为灰色对象。
以下图为例 就是将 D变更为了灰色,那么在此扫描的时候 会将D重新扫描 就可以访问到C了
SATB
snapshot-at-the-beginning 在GC执行的时候 如果发生了修改对象引用关系,那么垃圾回收器会记录删除对象的引用,这样可以达到 关系引用图是固定的(快照实现),当并发标记的时候 程序改变了某个对象的引用,会将该对象 的引用,存储至一个队列中(satb_mark_queue),后续再次遍历的时候 可以直接从队列中找到修改过的引用,从而方便重新标记 这个会在G1的垃圾回收器中说明G1垃圾回收器写屏障