zoukankan      html  css  js  c++  java
  • 垃圾回收的可触及性

    可触及性的3种状态:
    1.可触及的:从根节点开始,可以到达这个对象。
    2.可复活的:对象的所有引用都被释放,但是对象有可能在finalize()函数中复活。
    3.不可触及的:对象的finalize()函数被调用,并且没有复活,那么就会进入不可触及状态,不可触及的对象不能被复活,因为finalize()函数只会被调用一次。

    对象的复活
    /**
    * Created by xxd on 2017/4/4.
    */
    public class CanReliveObj {
    public static CanReliveObj obj;

    @Override
    protected void finalize() throws Throwable{
    super.finalize();
    System.out.println("CanReliveObj finalize called");
    obj = this;
    }

    @Override
    public String toString(){
    return "I am CanReliveObj";
    }

    public static void main(String[] args) throws InterruptedException{
    obj = new CanReliveObj();
    obj = null;
    System.gc();
    Thread.sleep(1000);
    if (obj == null){
    System.out.println("obj is null");
    }else{
    System.out.println("obj is useful");
    }
    System.out.println("the second gc");
    obj = null;
    System.gc();
    Thread.sleep(1000);
    if (obj == null){
    System.out.println("obj is null");
    }else{
    System.out.println("obj is useful");
    }
    }
    }
    运行结果如下
    第一次将obj设置为null后,进行GC,结果obj对象被复活。
    第二次将obj设置为null,并GC后,对象才被真正的回收。

    这是因为在第一次GC时,在finalize()函数调用之前,虽然系统中的引用已经被清除,但是作为实例方法finalize(),对象的this引用依然会被传入方法内部,如果引用外泄,对象就会复活。

    此时,对象又变为可触及状态。

    而finalize()函数只会被调用一次,因此,在第二次清除对象时,对象就无机会复活,因此就会被回收。

    注意:
    1.finalize()函数有可能发生引用外泄,在无意中复活对象;
    2.由于finalize()是被系统调用的,调用时间是不明确的,因此不是一个好的资源释放方案,推荐在try-catch-finally语句中进行资源的释放。

  • 相关阅读:
    linux driver ------ 交叉工具链(cross toolchain)
    Qt ------ 截图、获取鼠标指定的RGB值
    Qt ------ QWidget 自定义子类使用信号与槽(Q_OBJECT)后 stylesheet 失效
    Qt error ------ incomplete type 'QApplication' used in nested name specifier
    Qt ------ Q_UNUSED
    SpringCloud 组件Eureka参数配置项详解
    过滤器(Filter)与拦截器(Interceptor)的区别
    事务隔离级别
    事务四大特性
    get与post的区别
  • 原文地址:https://www.cnblogs.com/xxdfly/p/4a704d0fce24e2dca466c9962c336f15.html
Copyright © 2011-2022 走看看