垃圾回收机制

来源:互联网 发布:怎么注册淘宝会员名 编辑:程序博客网 时间:2024/06/01 07:59

/*************/
可耻的看了别人的博文~~~
/************/

垃圾回收算法主要有两种方式:
引用计数和可达性分析

引用计数原理
每次创建创建一个对象,就设置一个引用计数,每当这个对象被引用一次后,引用计数就加一。当一个引用失效时,引用计数就减一,当引用计数等于零时,就回收这个对象。
不过这个方法有个bug,当对象之间互相引用时,这个方法就gg了。
就像这个,无奈脸。

package testEpcc;public class GCTest {    private Object instance=new GCTest();    public static void main(String[] args) {        GCTest gc1=new GCTest();        GCTest gc2=new GCTest();        gc1.instance=gc2;        gc2.instance=gc1;        gc1=null;        gc2=null;    }}

两个对象互相引用,因为引用计数永远无法为0,因此不能自动释放。

可行性分析
用有向图来分析对象可不可达,当对象不可达的时候,并不能代表这个对象一定会被回收,它处于死缓状态,而一个对象真正被回收时,至少要经历两次标记。第一次标记的条件是,看这个对象是否覆盖过finalize()方法或者finalize()方法是否被虚拟机调用过。如果覆盖了finalize()方法但还没被虚拟机调用过,这时会标记它,该对象还有存活的机会,例如,在finalize方法中引用该对象。

如果进行第二次回收时,由于虚拟机已经调用过finalize()方法,就不会再调用它了,这时对象就直接死了。

package testEpcc;public class GCRoot {    private static GCRoot instance=null;    @Override    protected void finalize() throws Throwable {        // TODO Auto-generated method stub        super.finalize();        System.out.println("finalized执行");        instance=this;    }    public static void main(String[] args) {        instance=new GCRoot();        instance=null;        System.gc();        //因为finalize执行优先级较低,这里等待0.5秒        try {            Thread.sleep(500);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        if(null!=instance){            System.out.println("对象拯救成功");        }else{            System.out.println("对象被释放");        }        instance=null;        System.gc();        /*if(null!=instance){            System.out.println("对象拯救成功");        }else{            System.out.println("对象拯救失败");        }*/    }}
原创粉丝点击