Buz*_*ear 13 java memory-leaks memory-management
我相信开放流会导致java中的内存泄漏(至少java 1.6及更早版本确实存在这个问题).
但是,在搜索时(即使在这里),我发现有些人同意这一点,而其他人却没有.所以,如果我写这个程序:
import java.io.*;
public class CreatingMemoryLeak {
public static void main(String args[])
{
String s = "xxxxxxx";
InputStream in = new ByteArrayInputStream(ss.getBytes());
BufferedInputStream bf = new BufferedInputStream(in);
try {
while(bf.read()>0)
{
System.out.println("got it");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Here is a input stream " + s +" causing a memory leak");
}
}
Run Code Online (Sandbox Code Playgroud)
如果我没有bf明确关闭流,它会导致内存泄漏吗?
bma*_*ies 33
准确地使用与Java相关的术语"内存泄漏"非常重要.
在Java中,当您的代码永久保存引用时会发生内存泄漏,因此某些对象永远不会被垃圾回收.
在这种意义上,未能关闭流不是内存泄漏.具有本机资源的流具有终结器; GC最终将关闭它们.除非你持有对未封闭流的引用,否则它不是泄漏.
但是,除了内存泄漏之外还有其他类型的泄漏.大多数操作系统限制打开文件的数量.如果您未能关闭流,GC可能需要很长时间才能关闭它们; 最终结果可能是您用完了系统文件描述符,而您的代码无法再打开一个文件.有些人会称之为泄漏,但将其称为内存泄漏并不准确.
(至少java 1.6及更早版本确实存在这个问题).
任何版本的Java,就此而言,任何语言都有这个问题; 它不是特定于Java.
如果您掌握了需要系统资源的输入或输出句柄,则无论如何都需要释放它们.
Java必须Closeable表明您拥有的实例可能拥有或不拥有系统资源; 但如果不这样做.close(),你就会泄漏资源; 就这么简单.
例如,您可能有一个具有InputStream参数的方法; 好的,很好,但这是什么InputStream?是一个FileInputStream还是一个ByteArrayInputStream,甚至是别的什么?你无法知道.第一个需要正确关闭,但第二个不需要.
所以呢?.close()无论如何,他们都没有什么可失去的.你真的想抓住这个机会吗?
使用Java 6,您将需要使用Guava Closer,因为这是关闭所有资源的最安全的方法(并且JDK不提供这样的工具):
final Closer closer = Closer.create();
try {
final InputStream in = closer.register(openInHere());
final InputStream in2 = closer.register(...);
final OutputStream out = closer.register(...);
// do work with in, in2, out, other
} catch (WhateverException e) {
// IF WhateverException is not an IOException and you want to rethrow...
// throw closer.rethrow(e, WhateverException.class);
} finally {
closer.close(); // always safe
}
Run Code Online (Sandbox Code Playgroud)
使用Java 7,您可以使用try-with-resources来处理所有AutoCloseable资源(Closeable扩展):
try (
final InputStream in = ...;
// etc
) {
// work with AutoCloseable resources
} catch (WhateverException e) {
// deal with e, rethrow if necessary
}
Run Code Online (Sandbox Code Playgroud)
Closer和资源尝试之间的主要区别在于,对于后者,资源将被关闭, catch而Closer将关闭它们finally.
但同样:不要冒险.关闭它们.
| 归档时间: |
|
| 查看次数: |
11547 次 |
| 最近记录: |