概述
在垃圾回收算法中有许多,例如垃圾-清除,复制算法,垃圾-整理,后来在此基础上增加了分代(新生代/老年代)算法,每代都采取不用的回收算法以提高整体效率。
无论进行哪种程度的回收算法,都需要进行标记,用来区分垃圾与存活对象。而在整体区分是否回收的方式上分为两种:引用计数器方法和可达性分析算法。
引用计数器:通过为对象添加一个引用计数器,当被引用的时候进行加1操作,当引用失效的时候就进行减1操作,当引用计数器为0的时候便达到了回收条件,可以进行回收。
可达性分析算法:这个算法的基本思想就是通过‘GC Root’根向下进行搜索,所形成的路径成为引用链,当一个对象到GC Root根之间没有任何引用链连接的时候,便判断此对象可以被回收,也就是我们常说的可达。
三色标记
此方法就是根据可达性分析算法的思想进行标记与回收的,**CMS和G1**垃圾回收器就是用的此方法进行标记的
此过程便是标记过程,其中黑色表示对象本身以及以及他的成员变量均完成标记不是垃圾,灰色表示本身已完成标记但并未进行向下搜索的步骤,而白色则代表并未对这个对象进行任何标记。当利用三色标记法的时候我们往往会出现以下两种情况:
灰色指向白色的引用消失了,这种情况下不会产生问题,因为垃圾是一轮一轮回收的,此时白色便属于了浮动垃圾(这轮没清理掉。下轮清理也可以)。
而第二种则是会出现问题的情况:
灰色指向白色的引用消失了,增加了一条黑色指向白色的引用,此时因为黑色会被认为全部完成标识,便不会扫描下面的对象,这时候就会产生漏标的现象,此时白色会直接被清除掉。
针对第二种情况的解决方案:1)CMS的解决方案:把有新指向的引用的黑色变为灰色,但并发标记的时候还会产生漏标现象,所以CMS的remark阶段必须从头扫描一遍。2)G1的解决方案(SATB):在起始的时候做一个快照,当灰色指向白色的引用消失的时候,要把这个引用推到GC的堆栈中,保证白色还能被GC扫描到。