首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java和手动执行finalize

Java和手动执行finalize
EN

Stack Overflow用户
提问于 2008-08-26 18:51:42
回答 3查看 19.6K关注 0票数 18

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

这是一个大致的例子:

代码语言:javascript
复制
MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2008-08-26 19:23:06

根据这个简单的测试程序,JVM仍然会调用finalize(),即使您显式调用了它:

代码语言:javascript
复制
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(),而且几乎永远不会实现这个方法,因为不能保证是否以及何时会调用它。您最好手动关闭所有资源。

票数 30
EN

Stack Overflow用户

发布于 2013-12-20 23:22:19

要理解finalize的功能,必须了解垃圾收集器(GC)工作流。调用.finalize()不会调用垃圾收集器,也不会调用system.gc。实际上,finalize将帮助程序员将对象的引用声明为"unreferenced“。

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

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

有关详细说明,您也可以查看:javabook.computerware

票数 7
EN

Stack Overflow用户

发布于 2008-08-26 18:59:32

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

代码语言:javascript
复制
public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档