Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java和手动执行finalize_Java_Garbage Collection_Finalize - Fatal编程技术网

Java和手动执行finalize

Java和手动执行finalize,java,garbage-collection,finalize,Java,Garbage Collection,Finalize,如果我从程序代码中对一个对象调用finalize(),当垃圾收集器处理这个对象时,JVM还会再次运行该方法吗 这是一个近似的例子: MyObject m = new MyObject(); m.finalize(); m = null; System.gc() 对finalize()的显式调用是否会使JVM的垃圾收集器不在对象m上运行finalize()方法?JVM对任何给定对象调用finalize方法的次数不会超过一次。无论如何,您都不应该依赖finalize,因为不能保证它会被调用。

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

这是一个近似的例子:

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

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

JVM对任何给定对象调用finalize方法的次数不会超过一次。无论如何,您都不应该依赖finalize,因为不能保证它会被调用。如果调用finalize是因为需要执行清理代码,那么最好将其放入单独的方法中并使其显式,例如:

public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();

根据这个简单的测试程序,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");
}
输出为:

开始
定稿
定稿
完成


每个资源都说永远不要显式地调用finalize(),而且几乎从来没有实现过该方法,因为无法保证是否以及何时调用它。您最好手动关闭所有资源。

您必须了解垃圾收集器(GC)工作流才能了解finalize的功能。调用.finalize()将不会调用垃圾收集器,也不会调用system.gc。实际上,finalize将帮助编码器将对象的引用声明为“未引用”

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

引述:“在为某个对象调用finalize方法后,在Java虚拟机再次确定任何尚未终止的线程都无法再通过任何方式访问该对象之前,不会采取进一步的操作,包括准备完成的其他对象或类可能采取的操作,此时对象可能会被丢弃。“来自Java.Object.finalize()上的JavaAPI文档

有关详细说明,您还可以查看: