Java 垃圾回收中 finalize 方法怎么执行
finalize 方法的执行依赖于 jvm 的 finalizer 守护线程,该线程会轮询一个由 gc 触发的待处理队列。当对象被判定为不可达且拥有 finalize 方法时,gc 会将其注册到该队列,随后由守护线程取出并调用其 finalize() 方法。如果该方法抛出异常,jvm 会记录日志但不会中断其他对象的清理工作。

对象如何进入 Finalizer 队列
对象进入 Finalizer 队列发生在标记-清除或复制算法的存活分析阶段之后。当 HotSpot 虚拟机发现一个对象不再被任何根引用可达,并且该对象继承或重写了 java.lang.Object 的 finalize() 方法时,它不会立即销毁该对象,而是将其放入一个特殊的内存区域或直接链接到一个内部队列中。

public class DemoFinalize {
@Override
protected void finalize() throws Throwable {
System.out.println("Object is being finalized");
super.finalize();
}
public static void main(String[] args) {
DemoFinalize obj = new DemoFinalize();
obj = null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Finalizer 守护线程的工作机制
Finalizer 守护线程(Daemon Thread)在 JVM 启动时创建,其优先级较低。它通过一个无限循环不断从 ReferenceQueue 中获取即将被终结的对象引用。一旦获取到引用,线程就会调用该对象的 runFinalizer() 方法,进而触发 finalize() 的执行。这个过程是异步的,因此无法保证 finalize() 会在某个特定时间点之前执行。
finalize()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











