2

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

...
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)替换它们——即,“如果它没有坏,就不要修理它。”

鉴于这种情况,这实际上是资源泄漏吗?

4

3 回答 3

3

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

通常,您应该始终调用close最外层的流,这会波及到内部的流。

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

相关: try-with-resources 声明

于 2013-09-11T16:37:06.107 回答
2

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

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

于 2013-09-11T16:38:43.993 回答
0

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

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

于 2013-09-11T16:32:30.413 回答