zoukankan      html  css  js  c++  java
  • Java垃圾回收--判断可触及性

    博客搬家自https://my.oschina.net/itsyizu/blog/

    垃圾回收的基本思想:

    考察每一个对象的可触及性(从根节点开始是否可以访问到这个对象,如果可以,这说明当前对象正在使用,否则,说明这个对象已经不再使用了),一般来说,这个对象就需要被回收了。

    但事实上,一个无法触及的对象可以在一定的条件下复活自己,如果是这样,那么对它的回收就是不合理的,为此,需要给出一个对象可以触及性状态的定义。

    • 可触及的:从根节点开始,可以到达这个对象
    • 可复活的:对象的所有引用都被释放,但是对象有可能在finalize()函数中复活。
    • 不可触及的:对象的finalize()函数被调用,但是没有复活,那么就会进入不可触及的状态。

    代码来帮忙

    下面给出一个例子,该对象在finalize中复活了

    public class CanReliveObj {
        public static CanReliveObj obj;
        public void finalize()
        {
        try {
            super.finalize();
        } catch (Throwable ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
        }
        System.out.println("CanReliveObj finalize called");
        obj=this;
        }
        public String toString()
        {
        return "I am CanReliveObj";
        }
        public static void main(String [] args)
        {
        obj=new CanReliveObj();
        obj=null;
        System.gc();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
        }
        if(obj==null)
        {
            System.out.println("obj is null");
        }else
        {
            System.err.println("you can  use obj");
        }
        System.err.println("第二次gc");
        obj=null;
        System.gc();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
        }
        if(obj==null)
        {
            System.out.println("obj is null");
        }else
        {
            System.err.println("you can  use obj");
        }
    
        }
    }

    image

    第一次对该对象清理会调用它的finalize函数,虽然系统中的引用已经被清除,但是作为实例方法finalize,对象的this引用依然会被传入方法内部,如果引用外泄,对象就会复活。而finalize函数只会调用一侧,所以,第二次清楚对象的时候,对象就没有机会再复活。

    NOTICE

    finalize函数是一个非常糟糕的模式,不推荐大家使用finalize函数来释放资源。

    因为:
    >

    • finalize函数有可能发生引用外泄,在无意中复活对象.
    • 由于finalize是被系统调用的,调用的时间不明确,因此不是一个很好的资源释放方案,推荐在try-catch-finally语句中进行资源的释放
  • 相关阅读:
    简单的运动框架——分享给初学者
    Python数据分析学习日志(1. 书单)
    mysql恢复数据参考
    window cmd 杀掉 java.exe 进程
    转载: Ajax关于readyState和status的讨论
    开发问题bug记录
    vue基础part10
    vue基础part9
    vue基础part(7-8)
    vue基础part(4-6)
  • 原文地址:https://www.cnblogs.com/shugen/p/6862979.html
Copyright © 2011-2022 走看看