日期:2014-05-20  浏览次数:20601 次

请教内存泄漏
2个问题,请高手解答:

1.请问如果我定义一个   InputStream   in;
然后   in=ds.getInputStream();------------------ds是一个构造好的   javax.activation.datasource

如果   我在用完in变量以后   不调用   in.close   会不会出现   内存泄漏   ?

2.请问在下面的程序中会不会有内存泄漏?

InputStreamReader   inr     =   new   InputStreamReader(   zipFile.getInputStream(confEntry));
BufferReader   reader   =   new   BufferReader(   inr   );
try
{
....//do   something   using   reader
}
reader.close();

程序中没有调用     inr.close()   ,是否会造成   InputStreamReader对应的资源不能释放?


------解决方案--------------------
1、内存泄漏是不会的,但是可能要等很久才会正确回收,这样不是一件好事
2、reader.close是会内含调用了inr.close的,JDK中的类都是这样设计的,可以不需要显示调用inr.close
------解决方案--------------------
1.此问题不会造成内存泄漏,但第一个问题中如果另一个也读该文件的时候则不能够读,实际上是资源的一种浪费!等时间长了,才会将其释放掉!
------解决方案--------------------
我有一个不成熟的观点:java中就没有内存泄漏这一说。

内存泄漏是指动态申请的内存空间用完没有释放,这片空间是在进程的堆空间(heap),这里的空间没有名称,程序中只用一个指针来指向这片空间,并且这片空间被标记为已使用,如不及时释放,当指针变量离开作用域,也就是这个变量空间被弹栈(指针变量是存在栈空间的),就再也没有指向动态申请空间的指针,就没办法操作那片空间,那片空间就永远也没办法被释放(直到整个程序停止运行,进程空间被系统回收),一直被标记为已使用,这个局部一旦被重复调用,就会不停地申请空间不释入,内存不停被吞噬,就像泄漏了一样,有一天会被耗尽,然后进程被操作系统杀死,当然,如果是比较垃圾的操作系统,它会失去控制能力,而出现死机等。

java的自动垃圾回收机制:你可以只管申请内存,不用管释放,每申请一片内存,虚拟机会在一个表中做一个记录,并用一个引用指向这片空间,加上你的引用,至少有两个引用,如果你又把它赋值给其它的引用,将会在这个表中增加引用数目,当引用变量离开作用域,这个引用数会相应减少,到虚拟机自动执行垃圾回收时,会检查这个表,将只有一个引用的内存空间(系统引用)释放,因为这是在程序中没有引用指向它的空间,也就是垃圾。有了这种机制,所以我说java中不存在内存泄漏。但我也不确定这种说法是否是绝对正确的。

输入输出流不关闭是不会导致内存泄漏的,但一个系统同时能打开的流是有限的,既然是有限的,就是资源,如果程序中不及时关闭,就是资源浪费,同时也会导致其它使用这个文件的程序处于等待状态。

InputStreamReader inr = new InputStreamReader( zipFile.getInputStream(confEntry));
BufferReader reader = new BufferReader( inr );
这是包装模式,关闭时只需关最外层流,外层流的close方法会调用内层流的close方法。
另外一个原则是谁申请谁释放,如果一个流不是你new的,而是由方法中传进来的,就不要关闭,由new这个流的方法负责释放,避免外层方法出现异常。