三色标记:顾名思义使用三种颜色标记对象
白色:自身尚未被标记
灰色:自身被标记,但是成员变量还没完全被标记
黑色:自身已经被标记,成员也均被标记

当黑色A指向白色D的时候,并且灰色B指向白色D的引用消失的时候,就会存在漏标的现象。因为此时A是黑色的,不会再扫描了,扫描灰色B的时候找不到白色D,导致D对象扫描不到,从而产生漏标。
漏标产生的两个必要条件:
至少有一个黑色对象在自己被标记后指向了白色对象
删除了灰色对象到白色对象的直接或间接引用。
为了避免漏标,只要打破这两个必要条件之一即可。
CMS与G1)收集器都采用了三色标记算法:
CMS采用增量更新的方式打破第一个条件(黑色指向白色对象)

当A引用指向其他对象时,将A重新标记为灰色,下次扫描时,重新扫描A的成员遍历。
G1采用STAB(snapshot at the begining原始快照) 打破第二个条件(灰色指向白色对象的引用消失)

当B-> D的引用消失时,将D推送到GC堆栈,保证还能被GC扫描到。
STAB快照使用写前屏障将即将被修改的白色D对象信息保存到stab_mark_queue队列中,下次并发处理的时候会重新处理队列中对象信息。因为G1自身有一个RSet表存储了其他Region到改Region的引用信息,不需要扫描整个堆内存,可以快速通过RSet表找到存活的引用。
G1 的逻辑分代,物理不分代

每个分区都可能是年轻代,或者老年代,但同一时刻只能属于某一代。
G1 的RSet表

Rset表存储其他Region区域对象到本对象的引用信息,是的垃圾收集器不需要扫描整个堆内存就能找到垃圾,只需要扫描Rset表即可。