为何设置在java.lang.ref.Finalizer类静态块的断点未生效?
为什么Finalizer静态块的断点没触发?
核心原因很简单:java.lang.ref.Finalizer类并不是JVM启动时就会自动加载初始化的,它的初始化被严格延迟到「JVM需要处理带有可执行finalize()方法的对象回收」这个场景才会触发。
具体来说:
- 你的空
main()方法里没有创建任何重写了finalize()方法的对象,JVM完全没有调用Finalizer逻辑的需求,所以这个类根本不会被加载,静态块自然不会执行,断点当然不会生效。 - 哪怕你创建了普通对象(没重写
finalize()),JVM也不会碰Finalizer类——只有当对象拥有需要执行的finalize()方法时,它才会被加入Finalizer的待处理队列,进而触发Finalizer类的初始化和线程启动。
你可以修改代码验证这个结论:
public class TestFinalizer { @Override protected void finalize() throws Throwable { System.out.println("Finalize method executed"); super.finalize(); } public static void main(String[] args) { TestFinalizer obj = new TestFinalizer(); obj = null; // 让对象变为垃圾 System.gc(); // 主动触发GC try { Thread.sleep(1000); // 等待Finalizer线程完成处理 } catch (InterruptedException e) { e.printStackTrace(); } } }
运行这段代码时,JVM会因为要处理TestFinalizer对象的finalize()方法,被迫加载并初始化Finalizer类,这时候你设置的静态块断点就会正常命中了。
另外补充下:Java 8中Finalizer的设计就是这种懒加载模式,只有真正需要它的时候才会启动对应的线程,你的空main全程没触发任何相关操作,所以这个类一直处于未加载状态,静态块也就没机会执行。
内容的提问来源于stack exchange,提问作者guaner
相关产品推荐
相关产品推荐

