CMS垃圾收集器在并发标记时,使用的算法是三色标记,把对象在逻辑上分成三种颜色,如下图
如下图,一个对象A,他所引用的对象B是灰色的的,说明B已经被标记了,而A自身也被标记了,所以A就变成黑色的了,就说明它自身和它的成员变量都已被标记完成。B对象里有一个引用指向了白色的对象C,白色是代表没有被标记的对象,所以B就是灰色的,说明它只是自身被标记了,而它的成员变量没有被标记,而C对象就是白色的,说明是没有被标记的,是会被当成垃圾回收的。
漏标:
漏标是指,本来是存活的对象,但是由于没有被标记到,所以被当成垃圾回收了。
什么情况下产生漏标
如果在并发标记的过程中,可能会发生,B对象指向C对象的引用消失了,而A对象指向了C对象,因为这个时候A是黑色的,代表它自身和成员变量都已被标记完成了,所以下一次扫描的时候,就不会去管这个A对象了,也不会去管这个A里成员变量有没有被标记了,所以这个C是不会被标记到的,这时候这个C对象就被漏标,会被当成垃圾回收了。
解决方案
CMS使用的是incremental update(增量更新)这个方法,就是跟踪A指向C的引用增加,产生新的引用后,关注引用的增加。
原理就是把A的重新标记为灰色,因为灰色代表自身被标记,而成员变量未被标记,这个时候当下一次扫描的时候,一看这个A是灰色,那就说明它的成员标量没有被标记,就回去找A的成员标量去标记,这个时候就找到C了。