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

关于java内存回收的疑问,请求高人解答!
代码如下:
List<Person> list = new ArrayList<Person>();
for(int i=0;i<100;i++){
   Person p = new Person();
   list.add(p);
}
list=null;
System.gc();

假定调用System.gc();就立马可以回收内存
我这样写 list中的Person对象会被回收吗?
也就是我把list置空后 list里面的Person对象还可达吗?
------解决方案--------------------
假定调用System.gc();就立马可以回收内存。不一定立马要看当前CPU或JVM是否有空
我这样写 list中的Person对象会被回收吗? 不一定要看当前CPU或JVM是否有空
也就是我把list置空后 list里面的Person对象还可达吗? 逻辑上已经为空,实际上占用的内存不一定要看当前CPU或JVM是否有空
------解决方案--------------------
“假定调用System.gc();就立马可以回收内存”

还是不能确定会不会回收list中的Person,根据现代流行的分代gc,不能确定这些对象是在哪一代,且分代思想中的gc算法还有好多种
------解决方案--------------------
我觉得应该会被回收了,先看下这个:

http://developer.51cto.com/art/201001/175883.htm

如果System.gc()导致立刻回收 => full gc(全区搜索不可达对象,包括young generation,old generation 和 permanent generation) => 如果根据对象是否可达为回收唯一标准的话,list的失去引用直接导致所有p的失去引用,满足标准被回收。
------解决方案--------------------
你可以看一下jvm技术规范
里面有句话
大概意思是说
hotspot jvm中当你调用system.gc()时,jvm并不是马上开始进行垃圾回收,只是会马上调用finalize中的代码,真正的垃圾回收根据一个算法,找到吞吐率最低时候进行(这个事可以设置的)
------解决方案--------------------
我觉得这句话本身就有待商榷:
“假定调用System.gc();就立马可以回收内存”

API文档说的是:
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
------解决方案--------------------
那句话假定的其实也没必要,楼主貌似是想问Person对象最终是否会被回收,如果是内存泄露的话就不会被回收了。
我想list置null之后,这些list中的对象应该不再存在所谓的obsolete reference了吧