为什么我们重写java中的finalize()方法?

时间:2013-06-28 19:46:50

标签: java

当我们不知道何时可以运行任何给定对象的finalize()方法时,我们需要覆盖java中的finalize()方法?我们可以在finalize()中关闭什么类型的资源?什么是最好的GC会调用finalize()方法吗?

5 个答案:

答案 0 :(得分:4)

Why would you ever implement finalize()? 这个问题很好地涵盖了它。很少有理由这样做,但是它可能有用的一个例子是如果它们没有正确关闭则释放外部/本机资源。即使这样,正确结构化的代码也可以避免使用它。

答案 1 :(得分:1)

当您的类具有GC不会清除的资源(例如文件句柄或数据库连接)时,您应该覆盖finalize。这些资源应该在应用程序代码中清理,因为正如您所说,我们不知道何时运行finalize,但是最好还清理这些资源如果程序员搞砸并打开资源(如果在finalize运行时资源仍处于打开状态,那么终结器中的资源会将此作为警告或错误记录,因为这意味着应用程序代码未清除正确的资源)。

如果程序员通过例如正确清理对象的资源,

.NET可以禁止终结器。调用dispose,但不幸的是我不认为Java允许类似的模式。

答案 2 :(得分:0)

最好以您手动调用的close方法关闭资源。只有在对象被垃圾收集时才会调用finalize,这可能是在你完成对象使用后很久才会被调用。

我覆盖最终化的唯一原因是在我的应用程序中调试内存使用情况,其中某些对象未被收集。

答案 3 :(得分:0)

首先, finalization 的目的是在对象被垃圾收集之前为无法访问的对象提供执行任何清理的机会。
例如,关闭已打开的数据库连接。

应该覆盖finailze()方法,以使对象包含清理代码或处理在对象被垃圾回收之前应该完成的系统资源。

关于 GC调用finalize()方法的最佳机会是什么?,我们可以通过两种方式请求JVM执行垃圾收集:

  1. Runtime.getRuntime().gc();
  2. System.gc();
  3. 我们可以在finalize()中关闭什么类型的资源,答案有两种情况:

    1. 在完成目的后,将所有可用对象引用设置为null     创建对象已完成。

    2. 使引用变量引用另一个对象:将引用变量从对象中解耦并将其设置为引用另一个对象,因此在重新分配之前它引用的对象符合Grabage Collection的条件。

答案 4 :(得分:-1)

从我的笔记:

在对象被垃圾收集之前调用名为 finalize()的方法。不需要释放任何对象,但可能需要释放一些其他资源(例如打开的文件描述符)。

protected void finalize() throws IOException {
    if( fd != null ) closeIt() ;
}

理论上,终结器可能会做一些事情来防止对象被垃圾收集(例如在某些引用中存储“this”)。这绝不是一件有用的事情。

与构造函数不同,终结器不会自动链接。手动链接它们是一个非常好的主意,最好是在终结器的末尾:

protected void finalize() {
    // free resources consumed by this class
    // chain upward:
    super.finalize() ;
}