java成员变量何时被回收,以及监听回收

这篇文章来自网友,但是我忘记原文章是在哪里的了,但还是把这篇文章贴出来吧

一个对象是否被回收并不是仅仅靠当前对象是否被引用这么简单粗暴的方法去判断。

JVM中判断是否回收一个对象使用的是可达性分析算法,GC ROOT不可到达的节点都将会被标记上,一个对象如果被标记了两次就会被回收掉。至于这个可达性分析算法你可以自行百度一下,原理是很简单的。

那么用什么方法来监听一个对象是否被回收呢?当然用fianlize了;

请看代码:

public class Test {
    private static Test TEST= null;
    public static void main(String args[]) {
        TEST = new Test();
        TEST = null;
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(TEST);
    }
    @Override
    public void finalize() throws Throwable {
        System.out.println("要死了要死了要死了!");
    } 
}

执行结果

要死了要死了要死了!
null

那是不是执行了finalize后,对象就一定会被回收呢?其实也不一定finalize调用时对象仅有一次拯救自己的机会,如下:

public class Test {
    private static Test TEST= null;
    public static void main(String args[]) {
        TEST = new Test();

        TEST = null;
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(TEST);

        TEST = null;
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(TEST);
    }

    @Override
    public void finalize() throws Throwable {
        System.out.println("要死了要死了要死了!");
        TEST = this;
    } 
}

结果

要死了要死了要死了!
com.Test@1aa9f99
null

可以看到在第一次垃圾回收时,在finalize方法给当前回收对象赋值给了新的引用,避免了被回收,不过finalize方法一个对象只能调用一次,在第二次回收时将不会被调用了。

从上述两个例子中我们可以得出:finalize可以监听一个对象被回收,但是不能保证调用了finalize的对象一定会被回收,同时一个对象在第二次标记回收时是不会触发finalize的!如果想绝对监听一个对象是否被回收,只有在JVM里面添加参数-XX:+PrintGCDetails分析GC日志咯

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值