FinalReference类的功能

本文深入探讨Java中Finalize机制的工作原理,包括FinalReference和Finalizer类的作用,以及实现finalize()方法的类如何至少经过两次GC才能被回收。解析了finalizee类的概念,以及JVM如何通过Finalizer类和守护线程来执行对象的finalize方法。

FinalReference类的功能、jvm中finalize()方法的实现方式、为什么实现finalize()方法的类要至少经过两次gc才能回收。
FinalReference 的子类是Finalizer,FinalReference 类的权限是default的,Finalizer 类的权限是default的,并且有final修饰符,这两个类原则上不让开发者使用。他们和jvm配合实现java中对象实例被gc回收之前执行finalize方法。java中的类有构造方法,不像C++中有析构函数,finalize某种意义上是“析构函数”。

接下来看一下java是怎么实现finalize方法的。

首先需要解释一个概念,finalizee 类,finalize在超类Object中的原型是

protected void finalize() throws Throwable { }

如果子类复写了这个方法,既这个方法体不为空,这种类成为finalizee类,生成的实例时finalizee实例。这种实例jvm会和其他普通对象的实例多几个不同的处理步骤。

从FinalReference类中的结构来看。当一个finalizee对象被创建时,jvm会以当前对象为参数调用static void register(Object finalizee)方法。该方法封装成Finalizer实例并放置到ufinalized链表上。unfinalized是静态成员属性,在jvm实例中是唯一的。


final class Finalizer extends FinalReference { 
    private static ReferenceQueue queue = new ReferenceQueue();
    private static Finalizer unfinalized = null; // finalizee对象对应的Finalizer链表,jvm中全局的
    private static final Object lock = new Object();
    private Finalizer next = null,prev = null;
    private void add()
    private void remove() 
    private Finalizer(Object finalizee) {
        super(finalizee, queue);
        add();
    }
    static void register(Object finalizee) {
        new Finalizer(finalizee);
    }
    private void runFinalizer(JavaLangAccess jla) 
    private static void forkSecondaryFinalizer(final Runnable proc) 
    static void runFinalization() 
    static void runAllFinalizers() 
}

另一方面,在静态代码块中会有一个优先级较低的守护线程,该守护线程从queue中取出Finalizer,调用runFinalizer,runFinalizer运行该finalizee对象的finalize方法。runFinalizer中限制只会运行一次finalize方法。同时把当前finalizee对应的Finalizer从unfinalized链表中移除。是什么时候向queue中放置的Finalizer呢?gc判定当前的finalizee对象需要回收的时候,会把finalizee对应的Finalizer放到queue中,但此时该finalizee还未被回收。这些逻辑是Reference类中的逻辑(可以参看文章中“引用的内部逻辑”部分)。

FinalReference的流程

当运行完finalizee对象的finalize方法后,对应的Finalizer从unfinalized链表中移除、Finalizer中的referent置为null,finalizee对象变成孤立的对象。如果再次发生gc,finalizee对象会被回收,Finalizer会被回收。因此一个finalizee对象会至少经过两次的gc才能被真正回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值