Java Class.getResourceAsStream 应该关闭吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19598088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
should Class.getResourceAsStream be closed?
提问by BobLoblaw
I was wondering if this is required since when i use this method, the file is being read from the classpath. Does "not closing" it lead to a memory leak.
我想知道这是否是必需的,因为当我使用这个方法时,文件是从类路径中读取的。“不关闭”它会导致内存泄漏。
How can i test for such memory leaks?
如何测试此类内存泄漏?
采纳答案by jwatkins
You are assuming that Class.getResourceAsStream()
will always return a stream that points to a file inside your class' JAR file. This is incorrect. Your classpath may also contains folders, in which case Class.getResourceAsStream()
will return a FileInputStream
. Some other class loaders might also return other type of resources, such as remote files (in the case of a URLClassLoader).
您假设Class.getResourceAsStream()
将始终返回指向类的 JAR 文件中的文件的流。这是不正确的。您的类路径也可能包含文件夹,在这种情况下Class.getResourceAsStream()
将返回一个FileInputStream
. 其他一些类加载器也可能返回其他类型的资源,例如远程文件(在 URLClassLoader 的情况下)。
Even in the case of a JAR file, it is possible that the implementation maintain, by whatever mean, a persistant view inside the JAR file to the compressed bytes of the file you are accessing. Maybe it is holding upon a memory mapped ByteBuffer
...
即使在 JAR 文件的情况下,实现也可能通过任何方式在 JAR 文件中维护您正在访问的文件的压缩字节的持久视图。也许它正在坚持一个内存映射ByteBuffer
......
Why take the chance? You should always close streams (and any other Closeable, actually), no matter how they were given to you.
为什么要抓住机会?您应该始终关闭流(以及任何其他可关闭的,实际上),无论它们是如何提供给您的。
Note that since Java 7, the preferred method to handle closing anyresource is definitely the try-with-resources construct. It correctly handles several corner cases that are very hard to manage in hand written code, and yet it is almost as easy to write for you as if you had simply forgot about closing the resource. For example, you may use code like this:
请注意,从 Java 7 开始,处理关闭任何资源的首选方法绝对是 try-with-resources 构造。它正确地处理了在手写代码中很难管理的几个极端情况,但对您来说几乎就像您只是忘记关闭资源一样容易编写。例如,您可以使用这样的代码:
try (InputStream in = Class.getResourceAsStream("someresource.txt")) {
// Use the stream as you need to...
}
// Then forget about it... and yet, it has been closed properly.
As for detecting leaks, the best strategy is to obtain a memory dump at the time the VM is shut down, then analyze it with some tool. Two popular tools are jhatand Eclipse mat.
至于检测泄漏,最好的策略是在VM关闭时获取内存转储,然后用一些工具进行分析。两个流行的工具是jhat和Eclipse mat。
回答by Andrea
The type returned is an inputstream so, regardless the concrete implementation (which could change from version to version), you have a close() method that imho should be called.
返回的类型是一个输入流,因此,无论具体实现(可能因版本而异),您都有一个应该调用 imho 的 close() 方法。
No matter if that method is actually doing something useful with the current version.
无论该方法实际上是否对当前版本有用。
回答by Attila
As a rule of thumb you should close all streams (and ay other types that provide close functionality). It can lead ro resource leaks (memory is one type of resource).
根据经验,您应该关闭所有流(以及提供关闭功能的任何其他类型)。它会导致 ro 资源泄漏(内存是一种资源)。
Although there is automatic garbage collection that reclaims memory eventually when an object is no longer referred to, it might still hold native resources that might not be released. Also, if some other long-lived object (e.g. the classloader) keeps a hold on the resource, it will not be claimed by the garbage collector.
虽然当对象不再被引用时,自动垃圾回收最终会回收内存,但它可能仍然持有可能不会被释放的本机资源。此外,如果其他一些长期存在的对象(例如类加载器)持有该资源,垃圾收集器将不会声明它。
If your program is short lived, or f you only open a small number of resources, you might not run into problems, but resource leaks are hard to detect in long-running applications.
如果您的程序寿命很短,或者您只打开少量资源,您可能不会遇到问题,但在长时间运行的应用程序中很难检测到资源泄漏。