【问题标题】:AutoCloseable and garbage collection relationAutoCloseable 和垃圾回收的关系
【发布时间】:2016-05-20 10:38:05
【问题描述】:

所以我已经阅读了有关自动关闭界面的所有内容并尝试使用资源,但这让我想知道:

如果我不(忘记)包装一个实现 AutoCloseable 的类并尝试在使用该类的代码中使用资源,但该类确实从操作系统获取资源,会发生什么情况? 虽然不能保证 JVM 会决定何时调用其垃圾收集器,但当它决定时,它会调用 close() 方法吗?

如果没有,我会错过 C++ 的析构函数吗? :) 是否有类似的方法可以确保从该类的代码而不是用户的代码中,一旦对象应该被释放(例如超出范围),它将释放它占用的所有操作系统资源?

【问题讨论】:

    标签: java garbage-collection


    【解决方案1】:

    取决于班级。有些确实实现了finalize() 方法,在GC 收集对象时调用,并且确实调用了close();,但不能保证。

    请注意,尽管您可能会认为“是啊,Java 确实有析构函数!”这不是一回事,不建议您在自己的类中开始实现finalize()(我不记得在我 16 年的 Java 编程中写过一个)。

    当您忘记关闭资源时,您已经犯了错误,因此请改正。使用AutoCloseable 比以前方便多了。

    【讨论】:

    • 感谢您的回复,但我的主要困惑点保持不变:我不想依赖用户代码。用户是使用该类的任何代码。因此,如果某个地方的某个人确实忘记显式调用 close() 或以其他方式使用 try-with-resources,则不会发生灾难。当你写一些使用 close() 一些使用 finalize() 时,你的意思是垃圾收集器的一些实现吗?再说一遍:作为一个使用操作系统资源的类的设计者,我想尽我所能,这样即使是健忘的用户也可以:)我希望这是有道理的
    • 这里很可能没有什么有用的东西可以做。您可以实现finalize,但这只有在您直接与具有损坏API 的操作系统资源交互时才能实现。如果您使用的是来自java. 包的API,那么它几乎肯定会有一个适当的finalize 实现作为最后的手段。自己编写并没有什么好处。
    • 好的,所以只是为了确保:你们告诉我,没有明智的方法可以避免向该类添加以下文档:“使用此类时,请确保调用 close()方法,或使用 try-with-resources,如果您忘记这样做,资源可能会泄漏,具体取决于您的 gc 实现”。最重要的是,当误用这个类时,没有办法让编译器警告我的用户。这是正确的吗?
    • 没必要。像FileInputStream 这样的JDK 类已经实现了finalize(),所以资源被关闭了。对于您自己的课程,我会避免评论如此冗长的胡言乱语。如果用户正在阅读文档,他会看到AutoCloseableclose() 方法,可能还有一个关于如何使用该类的示例(如果有标准的习惯用法)。如果用户没有阅读文档,那么您为什么要关心?你不能让它变得万无一失,因为有很多傻瓜在尝试编程,你可以更好地度过你的时间。
    【解决方案2】:

    您无需添加任何此类文档。只需将其设为CloseableAutocloseable,每个人都会知道。最多在用于获取实例的方法/构造函数中添加一个简短的注释“不要忘记调用close()”。

    如果没有,这是我会错过 C++ 的析构函数的地方吗?

    当然,你会想念他们的。 Java 中没有真正的替代品。 finalize() 和朋友们都比较没用。在 GC 启动之前,您可能早就用完了资源(文件描述符等)。

    您可以使用finalize() 或类似名称来打印警告。如果对象在之前没有关闭的情况下被 GC'ed,那就是资源泄漏。

    有标记非关闭资源的静态分析工具。不知道,如果他们使用自定义对象,但我敢打赌他们会查看所有实现(自动)可关闭的类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-13
      • 2015-06-10
      • 2011-08-01
      • 2012-02-19
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      相关资源
      最近更新 更多