system.runfinalization()仅建议jvm尽力执行已入f-queue但未调用finalize()的对象的终结逻辑,不触发gc、不改变优先级、不保证执行;现代java推荐用try-with-resources、autocloseable或cleaner替代finalize。

System.runFinalization() 并不会让 JVM “优先”执行 finalize 方法,它只是建议 JVM 尽力去执行那些已被判定为可回收、但尚未运行 finalize() 的对象的终结逻辑——而且这个“尽力”不保证任何行为发生。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
换句话说:
它不改变执行顺序,不提升线程优先级,也不触发 GC;它只对已处于 finalizable 状态(即已入 F-Queue 队列)的对象,提示 FinalizerThread 尽快处理队列中的任务。
System.runFinalization() 的真实作用
- 它告诉 JVM:“请尽快运行那些已丢弃、但还没调用
finalize()的对象的方法。” - 实际是否执行、何时执行、执行多少个,完全由 JVM 决定(尤其是 FinalizerThread 的调度策略和当前队列状态)。
- 它不触发垃圾回收,也不把不可达对象变成
finalizable;只对已进入 F-Queue 且未执行finalize()的对象起作用。 - 如果 F-Queue 为空,或 FinalizerThread 正忙/被挂起/低优先级阻塞,该调用可能完全无效果。
为什么它不能“优先”执行?
- FinalizerThread 是一个低优先级守护线程(
Thread.MIN_PRIORITY),默认不抢占 CPU。 - 它从 F-Queue 取任务是串行、懒惰、非实时的,甚至可能因异常静默失败(
finalize()抛异常会被吞掉,不报错不中断)。 - JVM 规范明确写的是 “suggest that the JVM expend effort toward running…” —— 关键词是 suggest,不是 request 或 demand。
实际开发中该怎么对待它?
- ✅ 可在测试或调试场景中偶尔调用,辅助观察
finalize()是否被触发(比如配合System.gc()使用)。 - ❌ 绝不能用于资源释放主路径(如关文件、断连接),因为:
- 它不保证执行;
- 执行时机不可控(可能数秒、数分钟,甚至永不执行);
- 多次调用无叠加效果,也无排队保障。
- ⚠️ 不要与
System.gc()混淆:-
System.gc()→ 建议启动 GC(可能发现新finalizable对象); -
System.runFinalization()→ 建议处理已发现的finalizable对象(但不负责发现)。
-
替代方案:别依赖 finalize,改用明确机制
- 对文件、Socket、数据库连接等资源,使用:
-
try-with-resources(实现AutoCloseable); - 显式
close()/shutdown()方法;
-
- 对 native 资源(如 JNI 分配内存),可用
Cleaner(Java 9+ 推荐)或PhantomReference配合引用队列; - 若仍需兜底,
finalize()仅作为最后防线,且应在其中调用已有的显式清理方法(而非重复实现逻辑)。
Java 的终结机制本质是妥协产物,现代 JDK 已明确标记 finalize() 为 deprecated for removal(JEP 421, Java 21 起默认禁用,Java 22+ 彻底移除)。真正可控、可测、可维护的资源管理,永远建立在“主动释放”之上,而非等待 JVM 的不确定提醒。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










