【问题标题】:Why close() cannot be called on Closeable classes automatically?为什么不能在 Closeable 类上自动调用 close()?
【发布时间】:2013-09-11 07:32:44
【问题描述】:

我不明白。例如,我们在代码中有一个 OutputStream 类型的变量,我们应该在停止使用它时调用 close() ,这就是为什么它没有以这种方式实现的原因:GC 在清理时调用 close() 本身这个变量?

更新: 好的,到目前为止我的结论是:释放非托管资源不仅是释放内存,更重要的是我们现在不知道它背后的内部行为,它可能存在对此资源数量的限制(连接/处理程序的数量)这就是为什么我们需要尽快释放他们。我对吗?因为如果这一切都与内存有关,那么我不知道为什么 GC 不能像管理资源那样完成这项工作。

【问题讨论】:

  • 大多数流都实现了 finalize 会调用 close,但是没有保证会调用 finalize。当你知道你已经完成了它们时关闭你的流/阅读器是个好习惯
  • 关于你的更新:确切地说,它不是关于内存,而是关于 JVM 外部的东西。

标签: java garbage-collection unmanaged resource-cleanup


【解决方案1】:

close 在大多数情况下最终会被 GC 通过 finalize 方法自动调用(任何类都可以有这样的 finalize,在销毁对象时由 GC 调用;对于持有的 Closable 类型)资源一般会实现调用close)。当然,问题是您无法控制这种情况何时发生(如果有的话)。从您停止需要该对象开始可能是 10 秒或 10 分钟,但仍会用完分配的任何资源。因此,当您不再需要资源句柄时,清理它们是一种很好的方式。

此外,从 Java 7 开始,您实际上可以这样做:

try (BufferedReader br =
               new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

并且close会在try块结束时被自动调用。

有关详细信息,请参阅documentation

最后,为什么Closable和需要明确关闭的东西,这是针对不直接由JVM管理的资源,因此也不能自动被 GC 回收。此类资源用于实例文件、套接字或音频输出。

【讨论】:

  • 嗯,我们不关心不可关闭类型的局部变量不会被 GC 同时清理,为什么我们要关心可关闭类型的局部变量?
  • 因为 cloesable 通常表示对应的对象持有一些不受 JVM 直接控制的系统资源,例如文件描述符。
  • "对应的对象拥有一些不受JVM直接控制的系统资源"但是我们仍然可以调用close()吗?所以我们确实可以控制它还是什么?如果我们这样做了,那么 GC 会这样做,那么它可以自己做,不是吗?
  • 我认为这篇文章可能会更好地解释它:ibm.com/developerworks/java/library/j-jtp03216/index.html
  • 另外请注意,在 JLS 中实际上并不能保证终结器将永远运行;仅当 JVM 想要重用对象的内存时才需要运行它。如果不需要,JVM 有权从不回收对象的内存,并且 JLS 并没有说必须在程序退出之前运行终结器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 2022-01-13
  • 1970-01-01
  • 2011-03-18
  • 2011-06-23
  • 2015-09-29
相关资源
最近更新 更多