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语句中进行资源的释放
  • 相关阅读:
    java操作生成jar包 和写入jar包
    jboss配置jndi连接池
    windows 域的LDAP查询相关举例
    LDAP error Code 及解决方法
    HDU 6417
    CF1299D Around the World
    codechef Chef and The Colored Grid
    Educational Codeforces Round 82 (Rated for Div. 2)
    CF1237F Balanced Domino Placements
    CF1254E Send Tree to Charlie
  • 原文地址:https://www.cnblogs.com/shugen/p/6862979.html
Copyright © 2011-2022 走看看