一、三色标记之前JVM使用的什么算法?什么是三色标记?
1、 Mark-And-Sweep(标记清除)
实现原理: 标记初始时所有对象标记为 0,如果发现对象可达标记更新为 1,标记完成后将所有不可达对象(标记为0)清除,然后把所有对象标记重置为0方便下一次标记。
缺点
(1)标记时必须暂停整个程序
(2)不能进行异步操作
(3)标识 0 和 1不同阶段意义不同,新增对象很有可能被意外清除
(4)标记时间相对较长,系统不可接受
2、三色标记
优点
(1)可以异步执行
(2)中断时间短,不需要中断整个GC
三色含义
黑色:根对象,或本身与子对象都完成扫描
灰色:本身扫描完成,但是子对象未完成扫描
白色:未被扫描,或扫描完本身及子对象后不可达(垃圾对象)
二、漏标问题及解决办法
CMS解决方案 Incremental Update 算法(增量)
白色对象被黑色对象引用时,将黑色对象标记为灰色,让垃圾回收器重新扫描。
G1解决方案 SATB(snapshot-at-the-beginning)
我们在这个灰色对象取消对白色对象的引用之前,将这个引用记录下来,在最后标记的时候,再以这个引用指向的白色对象为根,对它的引用进行扫描
可以简单理解为,当一个灰色对象取消了对白色对象的引用,那么这个白色对象被变灰
这样做的缺点就是,这个白色对象有可能并没有黑色对象去引用它,但是它还是被变灰了,就会导致它和它的引用,本来应该被垃圾回收掉,但是此次GC存活了下来,就是所谓的浮动垃圾.其实这样是比较可以忍受的,只是让它多存活了一次GC而已,浪费一点点空间,但是会比增量更新更省时间.