当前位置: 首页 > 知识库问答 >
问题:

如何在Java中正确实现检测资源泄漏的终结器

商业
2023-03-14

假设我用close()方法创建了一些资源类来清理资源,如果有人忘记调用close(),我想重写finalize()来释放资源(并打印警告)。这怎么做才算妥当呢?

  • 是否只建议用于本机(JNI分配的)资源?
  • 如果从终结器中使用对另一个已终结的对象的引用,会发生什么?如果存在循环依赖项,我不明白垃圾收集器如何阻止您访问终结器可能已执行的对象。
  • 对于检测和/或处理资源泄漏,是否有更好的替代方法替代重写finalize()?
  • 实现终结器时还需要注意其他缺陷吗?

注意:我知道使用finalize()通常是个坏主意,而且不能保证调用它,还有其他几个问题在讨论这个问题。这个问题是关于如何在Java中实现终结器,而不是关于为什么应该(或不应该)。

共有1个答案

裴实
2023-03-14

在有效java(第二版)中,Joshua在第7项中详细介绍了如何做到这一点。他首先建议您几乎永远不要使用finalizers。但是,使用它的一个原因是只打印表示资源泄漏的日志语句。他说,这样做的一个好处是,有人可以扩展你的类,而不能正确地调用超级终结器。所以他建议在子类中做这样的事情:

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

这是为了确保,如果当前类中出现了问题,那么仍然会调用finally。这可能是一个糟糕的解决方案,因为它取决于对您的类进行子类的人。另一种解决方案是使用guardian对象文件来完成这项工作。这看起来像:

// 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
}

这是一种更干净的方法,因为您知道没有人可以覆盖该功能。

 类似资料:
  • 我试图理解不对任何流调用close()会如何影响系统的性能和功能。为了做到这一点,我创建了下面的测试类。

  • eclipse“潜在资源泄漏”警告不正确。 没有警告: 警告:潜在资源泄漏:“此位置可能未关闭响应” 为什么第二种方法会引起警告? 谢谢!

  • Eclipse Java警告:资源泄漏:“Unassigned Closeable Value”从不关闭 漏在哪里?

  • 大家晚上好。我是一个使用Java编程的完全初学者,我正在学习“扫描仪”,但是当我在Eclipse中键入这个基本代码时,我收到一条消息说“资源泄漏:‘扫描仪’永远不会关闭。 我做错了什么?

  • 我对Netty5(或4)中的引用计数bytebuf有些怀疑。我发现,当bytebuf超出生命周期时,我不释放它时不会发生任何事情,似乎bytebuf使用的内存可以正确地GCed。 在这个链接http://netty.io/wiki/reference-counted-objects.html中,它说设置JVM选项'-dio.netty.leakdetectionlevel=advanced'或调用