finalize()与GC的关系及替代方案
请说明finalize()方法在GC中的作用、问题以及为什么应该避免使用它?推荐的替代方案是什么?
回答
专业代码师
finalize()作用:
- Object类的方法,在GC回收对象前由Finalizer线程调用。
- 用于释放非Java资源(如Native套接字)。
- 对象可在finalize()中将this重新连接到GC Roots链,实现自救但只能一次。
存在问题:
- 执行时机不确定:GC时间不固定,finalize()可能永远不被执行。
- 性能问题:Finalizer线程优先级低,可能延缓回收,导致对象堆积触发OOM。
- 异常问题:finalize()抛异常不会导致对象释放,且不会抛出调用者。
- JVM规范不保证:规范明确不保证finalize()会被及时调用。
- JDK9已废弃:明确标注@Deprecated。
替代方案:
- try-finally:手动释放资源。
- try-with-resources:AutoCloseable接口,自动关闭。
- Cleaner(JDK9+):基于PhantomReference的轻量显式清理机制。
- 直接使用PhantomReference:更精细控制对象的回收时机。