对象已死?

原创
2014/07/02 17:25
阅读数 370

1、引用计数算法

     给对象中添加一个引用技术器,没当有一个地方引用它时,计数器值就加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收集器回收 


2、可达性分析算法

   主流的商用语言中,都是通过可达性分析来判断对象是否存活,其基本思路是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

   


    即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这个时候他们暂时处于“缓刑”阶段,真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的添加是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”

    如果这个对象呗判定为有必要执行finalize方法,那这个对象会放置在一个叫做F-Queue的队列之中,并在稍后由一个虚拟机自动建立的、低优先级的Finalizer县城区执行它。稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize方法中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,在第二次标记时它将被移除出“即将回收”的集合;如果对象这时候还没有逃脱,基本上就真的被回收了












展开阅读全文
打赏
0
6 收藏
分享
加载中

引用来自“dotNet-lc”的评论

swift为什么还用引用计数?
这是java不是swift
2014/07/03 09:15
回复
举报
swift为什么还用引用计数?
2014/07/02 21:17
回复
举报
更多评论
打赏
2 评论
6 收藏
0
分享
返回顶部
顶部