java Java和手动执行finalize
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java and manually executing finalize
提问by Iker Jimenez
If I call finalize()on an object from my program code, will the JVMstill run the method again when the garbage collector processes this object?
如果我finalize()从我的程序代码中调用一个对象,当垃圾收集器处理这个对象时,JVM还会再次运行该方法吗?
This would be an approximate example:
这将是一个近似示例:
MyObject m = new MyObject();
m.finalize();
m = null;
System.gc()
Would the explicit call to finalize()make the JVM's garbage collector not to run the finalize()method on object m?
是否显式调用finalize()使JVM的垃圾收集器不在finalize()对象上运行该方法m?
回答by Outlaw Programmer
According to this simple test program, the JVM will still make its call to finalize() even if you explicitly called it:
根据这个简单的测试程序,即使您明确调用了 finalize(),JVM 仍然会调用它:
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");
}
The output is:
输出是:
start
finalizing!
finalizing!
done
开始
定稿!
敲定!
完毕
Every resource out there says to never call finalize() explicitly, and pretty much never even implement the method because there are no guarantees as to if and when it will be called. You're better off just closing all of your resources manually.
那里的每个资源都说永远不要显式调用 finalize() ,甚至几乎永远不会实现该方法,因为无法保证是否以及何时调用它。您最好手动关闭所有资源。
回答by Ozan Aksoy
One must understand the Garbage Collector(GC) Workflow to understand the function of finalize. calling .finalize() will not invoke the garbage collector, nor calling system.gc. Actually, What finalize will help the coder is to declare the reference of the object as "unreferenced".
必须了解垃圾收集器 (GC) 工作流才能了解 finalize 的功能。调用 .finalize() 不会调用垃圾收集器,也不会调用 system.gc。实际上,finalize 将帮助编码器的是将对象的引用声明为“未引用”。
GC forces a suspension on the running operation of JVM, which creates a dent on the performance. During operation, GC will traverse all referenced objects, starting from the root object(your main method call). This suspension time can be decreased by declaring the objects as unreferenced manually, because it will cut down the operation costs to declare the object reference obsolete by the automated run. By declaring finalize(), coder sets the reference to the object obsolete, thus on the next run of GC operation, GC run will sweep the objects without using operation time.
GC 强制暂停 JVM 的运行操作,这会降低性能。在操作过程中,GC 将遍历所有引用的对象,从根对象(您的主要方法调用)开始。可以通过手动将对象声明为未引用来减少此暂停时间,因为它会降低通过自动运行声明对象引用已过时的操作成本。通过声明finalize(),coder将对象的引用设置为过时,因此在下一次GC操作运行时,GC run会在不占用操作时间的情况下清扫对象。
Quote: "After the finalize method has been invoked for an object, no further action is taken until the Java virtual machine has again determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, including possible actions by other objects or classes which are ready to be finalized, at which point the object may be discarded. " from Java API Doc on java.Object.finalize();
引用:“在为一个对象调用 finalize 方法之后,在 Java 虚拟机再次确定没有任何方法可以让任何尚未死亡的线程访问该对象之前,不会采取进一步的操作,包括准备完成的其他对象或类的可能操作,此时对象可能会被丢弃。”来自 Java API Doc on java.Object.finalize();
For detailed explanation, you can also check: javabook.computerware
详细解释也可以查看:javabook.computerware
回答by John Topley
The finalize method is never invoked more than once by a JVM for any given object. You shouldn't be relying on finalize anyway because there's no guarantee that it will be invoked. If you're calling finalize because you need to execute clean up code then better to put it into a separate method and make it explicit, e.g:
对于任何给定对象,JVM 永远不会多次调用 finalize 方法。无论如何您都不应该依赖 finalize,因为不能保证它会被调用。如果您调用 finalize 是因为您需要执行清理代码,那么最好将其放入一个单独的方法中并使其明确,例如:
public void cleanUp() {
.
.
.
}
myInstance.cleanUp();

