【问题标题】:Is there really a resource leak if I close the underlying stream?如果我关闭底层流,真的存在资源泄漏吗?
【发布时间】:2013-09-11 16:27:37
【问题描述】:

我在我们的一个程序上运行了一个动态代码分析工具,这种模式被识别为资源泄漏:

...
FileInputStream fileInputStream = new FileInputStream(file);
try {
    data = someMethod(new BufferedInputStream(fileInputStream));
    // Assume that someMethod(InputStream) internally reads the stream
    // until BufferedInputStream.read() returns -1.
    ...
}
finally {
    ...
    try {
        fileInputStream.close();
    } catch (IOException e) {
        ...
    }
}

具体来说,分析工具将new BufferedInputStream(...) 调用标记为资源泄漏,因为它从未关闭。但是,在此模式中,底层流 fileInputStream 已关闭,BufferedInputStream 超出范围。

注意:我最初发布问题时没有说明清楚,但我意识到这不是“最佳”实现。然而,如果这里没有事实上的资源泄漏,那么我们不太可能会在我们的遗留代码库中搜索该模式的所有实例并关闭外部流或用更新的构造(例如 try-with-resources)替换它们——即,“如果它没有坏,就不要修理它。”

鉴于这种情况,这真的是资源泄漏吗?

【问题讨论】:

    标签: java bufferedinputstream resource-leak


    【解决方案1】:

    这不太可能是实际的资源泄漏,但编写这样的代码绝对不是最佳实践。

    一般来说,您应该始终在最外层的流上调用close,这会波及到内层的流。

    如果您使用的是 Java 7,则可以使用新的 try-with-resources 语法并完全避免使用 finally 块。

    相关: The try-with-resources Statement

    【讨论】:

    • 谢谢;对于一般情况,try-with-resources 是一个很好的建议。但是,在我的特殊情况下,除非存在重大的事实上的资源泄漏,否则我们不太可能会花时间在现有代码库中查找和更新此模式的所有实例。我的次要目标可能与大多数人无关,但我也在尝试确定分析工具是否发现了真正的错误,或者它的启发式方法是否将误报标记为错误。
    • @rob 我认为问题在于如果不查看 someMethod 的实现,您无法确定是否发生了资源泄漏。我同意 Stephen 的观点,对于大多数合理的实现来说,这不是问题。
    • @rob 我对此类风格更改的一般规则是在遇到它们时一次清理一下。我同意你的观点,宣布公司范围内的授权在一夜之间改变这种模式是没有意义的。
    【解决方案2】:

    在这种情况下没有资源泄漏。但是,关闭 BufferedInputStream 的成本(或同时关闭)是最小的,因此添加(严格)不必要的关闭以使分析工具满意是最简单的。

    典型的静态分析工具在代码中寻找指示错误的结构模式。在这种情况下,模式匹配方法会误报资源泄漏。

    【讨论】:

    • 我还没有完成对工具静态分析器的所有结果的审查,但是这个特殊情况是通过动态分析检测到的。无论如何,很高兴知道这不是事实上的资源泄漏,因为我怀疑使用 BufferedInputStream 包装 InputStream(可能没有关闭它)作为性能优化在公司中是一种相当普遍的做法。
    【解决方案3】:

    因为 Java 没有解构器,超出范围的对象不一定会关闭流。 Java 确实有终结器,但不能保证它们会被调用。 BufferedInputStream 不一定会关闭。但是,由于底层流已关闭,我认为这并不重要。

    确保流已关闭是更好的做法,但可能并不重要。

    【讨论】:

      猜你喜欢
      • 2020-07-30
      • 2016-06-06
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 2019-04-02
      • 2012-09-13
      相关资源
      最近更新 更多