一、引用计数算法java
给对象中添加一个引用技术器,没当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任什么时候刻计数器值0的对象就是不可能再被使用的。其实现很简单,大部分状况下是一个不错的算法,可是它很难解决对象之间相互循环引用的问题。如:
算法
public class ReferenceCountGC { public Object instance = null; private static final int _1MB = 1024*1024; private byte[] bigSize = new bytep[2 * _1MB]; public static void testGC(){ ReferenceCountGC objA = new ReferenceCountGC(); ReferenceCountGC objB = new ReferenceCountGC(); objA.instance = objB; objB.instance = objA; objA = null; objB = null; //假设在这行发生GC,objA和objB是否能被回收? System.gc();
由于objA和objB互相引用这对方,致使它们的引用计数都不为0,这样就没法通知GC收集器回收 code
二、可达性分析算法对象
主流的商用语言中,都是经过可达性分析来判断对象是否存活,其基本思路是经过一系列的称为“GC Roots”的对象做为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证实此对象是不可用的。队列
即便在可达性分析算法中不可达的对象,也并不是是“非死不可”的,这个时候他们暂时处于“缓刑”阶段,真正宣告一个对象死亡,至少要经历两次标记过程:若是对象在进行可达性分析后没有与GC Roots相链接的引用链,那它将会被第一次标记而且进行一次筛选,筛选的添加是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,虚拟机将这两种状况都视为“没有必要执行”虚拟机
若是这个对象呗断定为有必要执行finalize方法,那这个对象会放置在一个叫作F-Queue的队列之中,并在稍后由一个虚拟机自动创建的、低优先级的Finalizer县城区执行它。稍后GC将对F-Queue中的对象进行第二次小规模的标记,若是对象要在finalize方法中成功拯救本身——只要从新与引用链上的任何一个对象创建关联便可,在第二次标记时它将被移除出“即将回收”的集合;若是对象这时候尚未逃脱,基本上就真的被回收了class