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

Java 内存泄露问题
一个外企面试题,题目大致意思是:
void fun() {
  String s = new String("abc");
  String[] a = new String[1];
  a[0] = s;
  s = null;
}
问"abc"这块内存啥时候释放?
答案是内存泄露了。
难道是因为s在栈内存,而a在堆内存的缘故吗?

------解决方案--------------------
public class MeL {
public static void main(String[] args){
Test m=new Test();
Test[] a=new Test[1];
a[0]=m;
m=null;
System.gc();
}
}

class Test{
public static long counter=0;
@Override
protected void finalize() throws Throwable {
System.out.println("被回收"+(++counter)+"次");
}
}

测试结果:没有被回收, 说明没有“泄露”
------解决方案--------------------
探讨
其实大家回答的都没有错 但是我想这个问题的提问点在于fun方法执行的时候,也就是方法体内,String s = new String("abc"); 这条语句执行时创建的abc对象什么时候销毁了  其实fun方法内并没有显式地销毁这个abc对象 因此是泄露了

------解决方案--------------------
Java的内存泄漏指的是有引用的无用对象。比如说

Object[] objs=new Object[2];
objs[0]=new Object();
objs[1]=new Object();
objs[0]=null;

objs[0]的空间会一直存在与代码生存期,直至退出。所以称之为Java内存泄露。

拙见
------解决方案--------------------
昨天刚在网上看了一篇关于内存泄露的文章, 文章中提出:
java的垃圾回收机制采用的是有向图的形式来进行判断, 图中无法到达的点(即不会再被引用的变量)将会被回收.
但是java编码时存在这样一种情况: 在有向图中有边连接到某个点, 但是在程序中将不会再引用.
如下面的代码:
Java code

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
Object o=new Object();
v.add(o);
o=null;
}
//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。