如何正确地实现终结在Java检测资源泄漏(How to properly implement a f

2019-09-22 12:26发布

比方说,我已经创造了一些资源类的清理资源close()方法,我想重写的finalize()以释放资源(并打印警告)如果有人忘记调用close()。 这可怎么得当?

  • 难道只推荐用于本地(JNI分配)的资源?
  • 如果你使用到已经敲定另一个对象的引用,从一个终结,会发生什么? 如果有循环依赖,我没有看到垃圾收集器如何阻止您访问对象,它们的终结可能已经执行。
  • 是否有没有更好的方法来覆盖的finalize(),用于检测和/或处理资源泄漏?
  • 任何其他陷阱要注意执行终结的时候?

注:我知道,使用敲定()通常是坏主意,而且它不能保证被调用,也有讨论这个其他的几个问题。 这个问题是特别了解如何在Java中实现一个终结,不是为什么你应该(或者不应该)。

Answer 1:

在有效的Java(第2版) ,约书亚就转至编号7的细节你如何能做到这一点。 他首先建议你应该几乎从来不使用finalizer秒。 然而,一个理由去使用它仅打印日志声明说您有一个资源泄漏。 他说,平局背对着做这种方式是,有人可以扩展你的类并不能正确调用父类的终结之一。 因此,他建议做这样的事情在子类:

// Manual finalizer chaining
   @Override protected void finalize() throws Throwable {
       try {
           ... // Finalize subclass state
       } finally {
           super.finalize();
   } 
}

这是为了确保,如果事情在当前类打破了finally还是会被调用。 这可能是一个坏的解决方案,因为它取决于谁是继承类的人。 另一种解决方案是使用一个守护对象文件完成这件事。 这看起来像:

// Finalizer Guardian idiom
   public class Foo {
// Sole purpose of this object is to finalize outer Foo object
      private final Object finalizerGuardian = new Object() {
         @Override protected void finalize() throws Throwable {
            ... // Finalize outer Foo object
         }
      };
      ...  // Remainder omitted
}

这是一个更简洁的方法,因为你知道,没有人可以覆盖该功能。

建议的方式来关闭资源依然贯彻Closeable ,并确保它是由用户关闭。 作为Josuha建议,你不应该在做任何时间敏感操作finalize方法。 该JVM可以选择在未来某个时候作为运行它。 如果你根据这个方法做的提交或一些重要的事情,然后这是一个坏主意。



Answer 2:

难道只推荐用于本地(JNI分配)的资源?

不可以。您的使用情况也是终结一个有效的。 我的意思是记录资源泄漏。

如果你访问已经敲定另一个Java对象,在终结会发生什么?

如果您仍然可以访问它,它没有最终确定。 或者,也许我失去了你的问题的东西。

我现在知道了。 这可能是A和B都符合垃圾收集和他们之间有一个参考的情况下。 它应该是没有问题,因为默认情况下finalize()什么都不做。 如果你写为您的自定义对象finalize()方法,你应该写你的代码独立的,他们最终确定的顺序。 你也应该警惕为基准成为null与相应的对象可能已经被垃圾收集。

是否有没有更好的方法来覆盖的finalize(),用于检测和/或处理资源泄漏?

我使用终结时,检测和记录/警告对泄漏不处理它认为最重要的事情。 并记录这种泄漏的最佳时刻是之前的资源对象进行垃圾回收。 因此终结是一个天生适合这个。

我想强调这一点:我不会用终结处理程序员是忘了关资源,而是要告诉他,他需要修复他的代码。

任何其他陷阱要注意执行终结的时候?

这似乎也有与具有终结对象的性能损失。 你应该做一个测试看它是如何为您服务。 如果有一个重要的性能损失,我会试着去想像一个机制,使用终结只是在开发时登录资源泄漏。

而继承与终结的对象时,由阿米尔Raminfar的建议照顾。

一两件事:看一看的[源代码FileInputStream][1][FileOutputStream][2]他们使用终结出于同样的原因。



文章来源: How to properly implement a finalizer for detecting resource leaks in Java