读书人

JVM内存分析系列(5)浅谈finalize()方

发布时间: 2013-12-29 13:07:03 作者: rapoo

JVM内存分析系列(五)浅谈finalize()方法
根搜索算法中不可达对象在回收之前,要进行二次标记。
第一次标记时会进行一次筛选:筛选的条件是是否有必要执行finalize()方法。
当对象没有覆盖finalize()方法,或者finalize()被虚拟机调用过,则虚拟机认为没有必要执行finalize()方法。
如果这个对象有必要执行finalize(),则会放在一个队列里,以一个低优先级的线程进行执行finalize()方法进行二次标记,如果在finalize()方法中,对象重新回到引用链上(比如this赋值给其他引用链上的对象),则该对象不被回收,而移出该队列。
注意:finalize()方法只被调用一次,如果这个对象在GC时被调用过一次finalize()方法,则第二次GC的时候,就会被判断为没有必要执行finalize()而被直接回收。
另外finalize()能做的所有工作,都可以通过try-finally更好、更及时的解决。所以请忘掉finalize().

package System.gc;/** * @author piaohailin * @date   2013-12-28*/public class TestGc {    public static TestGc HOOK;    @Override    protected void finalize() throws Throwable {        super.finalize();        TestGc.HOOK = this;        System.out.println("finalize");    }    /*          输出结果    finalize    HOOK is alvie    HOOK is dead     */    public static void main(String[] args) throws Exception {        HOOK = new TestGc();        HOOK = null;        System.gc();//第一次GC,符合有必要要执行finalize的条件        Thread.sleep(1000);//Finalizer线程优先级较低,所以要等一会        if (HOOK != null) {            System.out.println("HOOK is alvie");        } else {            System.out.println("HOOK is dead");        }        HOOK = null;        System.gc();//第二次GC,因为已经执行过一次finalize,所以没有必要进行二次标记        Thread.sleep(1000);//Finalizer线程优先级较低,所以要等一会        if (HOOK != null) {            System.out.println("HOOK is alvie");        } else {            System.out.println("HOOK is dead");        }    }}

读书人网 >软件架构设计

热点推荐