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类中的逻辑(可以参看文章中“引用的内部逻辑”部分)。

当运行完finalizee对象的finalize()方法后,对应的Finalizer从unfinalized链表中移除、Finalizer中的referent置为null,finalizee对象变成孤立的对象。如果再次发生gc,finalizee对象会被回收,Finalizer会被回收。因此一个finalizee对象会至少经过两次的gc才能被真正回收。
————————————————
版权声明:本文为优快云博主「玩转生活」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/csdn_app/article/details/103994271

深入探讨Java中FinalReference类的功能,jvm如何通过Finalizer实现finalize()方法,及为何finalizee类实例需经两次GC才被回收。解析finalize()方法在Java对象生命周期中的作用。
1062

被折叠的 条评论
为什么被折叠?



