悲剧艺术! finalize方法实现对象的自我拯救

生存还是死亡

C++必须手动释放内存, 而Java有Garbage Collection(垃圾回收机制), 自动释放内存, 那么gc是如何判断一个对象是否已经死亡, 是否该回收它了? 这就需要一个垃圾回收算法

可达性分析算法

在Java中使用的是可达性分析算法, 就是对象到gc roots是否直接或者间接性可达, 可达就还活着, 不可达就是死了, 要回收了
在这里插入图片描述
在这张图中, Object1、Object2、Object3是连在GC Roots上的, 而Object4没有, Object4就很有可能快被gc回收了

什么是finalize方法

finalize英文是终结的意思, 我认为这个方法可以理解为每个对象的"最后遗言", 快要被gc回收前执行的方法 ,不过有没有说遗言的机会还不一定呢…

执行finalize方法的时机

由于垃圾回收的不确定性, gc不能保证一个对象的finalize方法一定会被执行, 即便是System.gc()亦或者是System.runFinalization()也仅仅是提醒JVM要进行垃圾回收了, 仅仅是个建议, 到底要不要执行, 还是JVM说了算
一个对象死亡消失前, 至少要被标记两次, 第一次就是JVM通过可达性算法检测到它无法连接到gc roots, 如上面的Object4, 它会被标记一次并放入一个即将送往"断头台"的队列中, 如果这个对象没有重写finalize方法或者已经执行过finalize方法,它就会被标记第二次,基本死翘翘了.
所以,finalize必须要重写才有可能执行, 而且最多只会执行一次.
那假如我们在finalize方法中让对象重新连接上GC Roots, 那不就可以救活它了吗?finalize方法好比是它一块唯一的、一次性的"免死金牌",像是电视里面骑着马赶来大喊一声"刀下留人"的场景, 有没有点像, 哈哈

实现对象的自我拯救

public class FinalizeDemo {

    //声明一个引用
    private static FinalizeDemo finalizeDemo = null;

    //判断对象是否可达gc roots
    public static void isAlive() {
        if (FinalizeDemo.finalizeDemo != null) {
            System.out.println("我还活着!");
        } else {
            System.out.println("我死了..");
        }
    }

    @Override
    protected void finalize() throws Throwable {
        //把自身赋值给声明的引用,连接上gc roots
        finalizeDemo = this;
        System.out.println("连上GC roots, 抓住了救命稻草!");
    }

    public static void main(String[] args) {
        //new一个对象,对gc roots不可达, 即将面临死亡
        new FinalizeDemo();
        //建议gc进行垃圾回收,并执行finalize方法
        System.gc();
        System.runFinalization();
        //看看它死了还是活着
        FinalizeDemo.isAlive();
        //断开和gc roots的连接,现在为不可达
        finalizeDemo = null;
        System.gc();
        System.runFinalization();
        FinalizeDemo.isAlive();
    }
}

在主方法中,new了一个即将面临被回收的对象, 它通过finalize方法连接上gc roots才捡回了一命,当它断开连接后, 又面临着即将被回收的命运, 本想再次调用finalize方法救自己, 可是它的finalize方法已经被执行过一次了, 不会再执行了,所以只能"死亡"了
运行结果:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值