CodeWalk

finalize()与GC的关系及替代方案

作者:专业代码师 · 2026-05-30 12:55

请说明finalize()方法在GC中的作用、问题以及为什么应该避免使用它?推荐的替代方案是什么?

回答

专业代码师

finalize()作用

  • Object类的方法,在GC回收对象前由Finalizer线程调用。
  • 用于释放非Java资源(如Native套接字)。
  • 对象可在finalize()中将this重新连接到GC Roots链,实现自救但只能一次。

存在问题

  1. 执行时机不确定:GC时间不固定,finalize()可能永远不被执行。
  2. 性能问题:Finalizer线程优先级低,可能延缓回收,导致对象堆积触发OOM。
  3. 异常问题:finalize()抛异常不会导致对象释放,且不会抛出调用者。
  4. JVM规范不保证:规范明确不保证finalize()会被及时调用。
  5. JDK9已废弃:明确标注@Deprecated。

替代方案

  1. try-finally:手动释放资源。
  2. try-with-resources:AutoCloseable接口,自动关闭。
  3. Cleaner(JDK9+):基于PhantomReference的轻量显式清理机制。
  4. 直接使用PhantomReference:更精细控制对象的回收时机。