深入理解java虚拟机--生存还是死亡

在进行过可达性分析后的对象也不一定是非死不可的,该对象进行可达性分析后,发现没有与GC Roots相连接的引用链,

  • .这个对象就会第一次被标记起来;对对象是否必要执行finalize函数进行判断;(已经被GC调用过finalize方法或者没有重写finalize方法都认为是没有必要执行该finalize函数的)
  • F-Queue队列中存放该对象,优先级较低的Finalizer会去执行它;Gc 会对这个队列里面的对象再进行一次标记,如果在finalize方法中,对象没有自己自救的话,它就会被标记回收
  • finalize方法自救自己的办法是:重新与引用链上面的任何一个对象建立连接,或者把自己this赋值给某个类或对象的成员变量
/**
1.对象可以在GC时自救
2.自救的办法只有一次,因为一个finalize方法最多只能被调用一次
**/
public class FinalizeEscapeGC {

    public static FinalizeEscapeGC SAVE_HOOK = null;
    public void isAlive(){
        System.out.println("yes,I am still alive :)");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed !");
        FinalizeEscapeGC.SAVE_HOOK = this;
    }

    public static void main(String [] args) throws InterruptedException {
        SAVE_HOOK = new FinalizeEscapeGC();
        //对象第一次成功拯救自己
        SAVE_HOOK = null;
        System.gc();
        //因为finalize优先级很低,所以延迟0.5s以等待它;
        Thread.sleep(500);
        if(SAVE_HOOK != null){
            SAVE_HOOK.isAlive();
        }else{
            System.out.println("no, i am dead :(");
        }

        //下面这段代码再执行一遍,验证对象是不是可以成功
        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500);
        if(SAVE_HOOK != null){
            SAVE_HOOK.isAlive();
        }else{
            System.out.println("no, i am dead :(");
        }
    }

}

结果如下:

finalize method executed !
yes,I am still alive :)
no, i am dead :(

  • 并不鼓励使用这种办法来拯救对象,它的运行代价高昂,不确定性大,无法保证顺序;
  • finalize方法能做的所有工作,try-finally也可以做的更好,更及时,所以希望忘记这个方法的存在;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值