关闭

垃圾收集与对象生命拯救

发表于:2012-11-15 10:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:chunqiuwei    来源:51Testing软件测试网采编

  Java是根据根搜索算法来判断对象是否存活的。基本思路是:通过一系列名为“GC Roots”的对象作为起点,向下搜索锁走过的路径(称为引用链),当一个对象与GC Roots之间的连接是断开的,也就是对象与GC Roots之间是不可达的时候,该对象就是“不可用”的,注意只是不可用的而不是该对象已经死了。这时候该对象只是暂时处于死刑的“缓刑”阶段。既然是缓刑,就可以补救回来。

  其实要真正地宣告一个对象是否死亡至少要经历两次标记过程

  A、处于“缓刑”状态的对象,会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖此方法或者finalize()的方法已经被虚拟机调用过,在这两种情况都是为“没有必要执行”finalize()方法

  B、Finalize()方法是对象逃离死亡命运的最后一次机会,稍后GC会对对象进行第二次小规模的标记,如果对象要在该方法中拯救自己------只需要重新与GC Roots引用链上的任何一个对象建立关联即可。譬如把自己(this关键字)赋值给某个类的变量或对象的成员变量,那在第二次标记时它就会被移除出“即将回收”的集合,如果这个时候该对象还没有逃脱,那么该对象就真的里死亡不远了

  代码说明如下

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package x;

/**
 *
 * @author Arthur
 */
public class FinalizeEscapeGc {

    private int count = 0;
    private static FinalizeEscapeGc fec = new FinalizeEscapeGc();

    public FinalizeEscapeGc() {
    }

    public static void main(String[] args) throws InterruptedException {

        //对象第一次成功拯救自己
        fec = null;
        System.gc();
        ////显然输出为null
        System.out.println(fec);
        //因为finalize优先级很低,暂停一秒,以等待它
        Thread.sleep(1000);
        //打印x.FinalizeEscapeGc@c17164,说明成功拯救
        System.out.println(fec);
    
       
        //第二次次拯救失败
        fec = null;
        //显然输出为null
        System.out.println(fec);
      
        System.gc();
        //因为finalize优先级很低,暂停一秒,以等待它
        Thread.sleep(1000);
        //输出为null
        System.out.println(fec);
       

    }

    @Override
    public void finalize() throws Throwable {
        super.finalize();
        System.out.println("执行finalize方法");
        fec = this;

    }

    public int getCount() {
        return count;
    }
}

  注意finalize方法是被GC收集器触发,如果注释掉System.gc()注释掉的话,是不会执行finalize方法的。

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号