Java并手动执行finalize

如果我从程序代码中调用一个对象的finalize() ,那么当垃圾收集器处理这个对象时, JVM是否仍会再次运行该方法?

这将是一个近似的例子:

 MyObject m = new MyObject(); m.finalize(); m = null; System.gc() 

显式调用finalize()会使JVM的垃圾收集器不在对象m上运行finalize()方法吗?

根据这个简单的测试程序,即使你明确地调用它,JVM仍然会调用finalize():

 private static class Blah { public void finalize() { System.out.println("finalizing!"); } } private static void f() throws Throwable { Blah blah = new Blah(); blah.finalize(); } public static void main(String[] args) throws Throwable { System.out.println("start"); f(); System.gc(); System.out.println("done"); } 

输出是:

开始
定稿!
定稿!
DONE

那里的每一个资源都表示永远不会明确地调用finalize(),甚至几乎都没有实现该方法,因为无法确定是否以及何时调用它。 你最好手动关闭所有资源。

必须了解垃圾收集器(GC)工作流以了解finalize的function。 调用.finalize()不会调用垃圾收集器,也不会调用system.gc。 实际上,最终确定将有助于编码人员将对象的引用声明为“未引用”。

GC强制暂停JVM的运行操作,这会对性能造成影响。 在操作期间,GC将从根对象(主方法调用)开始遍历所有引用的对象。 通过手动将对象声明为未引用,可以减少此暂停时间,因为它将降低操作成本,以通过自动运行声明对象引用过时。 通过声明finalize(),编码器将对象的引用设置为过时,因此在下一次运行GC操作时,GC运行将扫描对象而不使用操作时间。

引用:“在为一个对象调用了finalize方法之后,在Java虚拟机再次确定不再有任何方法可以通过任何尚未死亡的线程访问该对象之前,不会采取进一步的操作,包括可以最终确定的其他对象或类的可能动作,此时可以丢弃该对象。“来自Java API Doc,java.Object.finalize();

有关详细说明,您还可以检查: javabook.computerware

对于任何给定对象,JVM永远不会多次调用finalize方法。 你不应该依赖finalize,因为不能保证它会被调用。 如果您正在调用finalize,因为您需要执行清理代码,那么最好将其放入单独的方法中并使其显式化,例如:

 public void cleanUp() { . . . } myInstance.cleanUp();