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

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

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

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

如果程序员通过调用dispose正确清理了对象的资源,.NET允许你压缩终结器,但不幸的是我不认为Java允许类似的模式。

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

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

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

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

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

  1. Runtime.getRuntime().gc();
  2. System.gc();

我们可以在finalize()中关闭什么类型的资源 ,答案在两种情况下:

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

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

从我的笔记:

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

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

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

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

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