面试中如何回答JVM三色标记?详细原理分析(细节)

在并发标记的过程中,因为标记期间应用线程还在继续跑,对象间的引用可能发生变化,多标和漏标 的情况就有可能发生。这里引入“三色标记”来给大家解释下,把Gcroots可达性分析遍历对象过程 中遇到的对象, 按照“是否访问过”这个条件标记成以下三种颜色:

标记过程:1.初始时,所有对象都在 【白色集合】中;2.将GC Roots直接引用到的对象挪到 【灰色集合】中;3.从灰色集合中获取对象:将本对象引用到的其他对象全部挪到 【灰色集合】中;将本对象 挪到 【黑色集合】里面。重复步骤3.4,直至【灰色集合】为空时结束。结束后,仍在【白色集合】的对象即为GC Roots 不可达,可以进行回收

多标-浮动垃圾在并发标记过程中,如果由于方法运行结束导致部分局部变量(gcroot)被销毁,这个gcroot引用的对象之前又被扫描过 (被标记为非垃圾对象),那么本轮GC不会回收这部分内存。这部分本应该回收但是没有回收到的内存,被称之为“浮动 垃圾”。浮动垃圾并不会影响垃圾回收的正确性,只是需要等到下一轮垃圾回收中才被清除。 另外,针对并发标记(还有并发清理)开始后产生的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分 对象期间可能也会变为垃圾,这也算是浮动垃圾的一部分。漏标-读写屏障漏标只有同时满足以下两个条件时才会发生:条件一:灰色对象 断开了 白色对象的引用;即灰色对象 原来成员变量的引用 发生了变化。 条件二:黑色对象 重新引用了 该白色对象;即黑色对象 成员变量增加了 新的引用。漏标会导致被引用的对象被当成垃圾误删除,这是严重bug,必须解决,有两种解决方案: 增量更 新(Incremental Update) 和原始快照(Snapshot At The Beginning,SATB)增量更新就是当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来,等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次。 这可以简化 理解为, 黑色对象一旦新插入了指向白色对象的引用之后, 它就变回灰色对象了。原始快照就是当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录在 并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次,这样就能扫描 到白色的对象,将白色对象直接标记为黑色(目的就是让这种对象在本轮gc清理中能存活下来,待下 一轮gc的时候重新扫描,这个对象也有可能是浮动垃圾) 以上无论是对引用关系记录的插入还是删除, 虚拟机的记录操作都是通过写屏障实现的。 写屏障实现原始快照(SATB):当对象B的成员变量的引用发生变化时,比如引用消失(a.b.d = null),我们可以利用写屏障,将B原来成员变量的引用对象D记录下来:写屏障实现增量更新: 当对象A的成员变量的引用发生变化时,比如新增引用(a.d = d),我们可以利用写屏障,将A新的成员变量引用对象D 记录下来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值