看代码
while(...){
List list =new arraylist
list.add();
}
请问进入下一次循环的时候 上一次循环产生的list能够被gc回收吗
上面的说的不对,回收不回收,jvm说了算,并不是立刻就回收
jvm启动参数上加上gc的日志-XX:+PrintGCDetails
[code="java"]
public class TestGc
public static void main(String[] args) {
int i=1000;
while(i-->0){
List l = new ArrayList();
for(int j=0;j++<1000;l.add(Integer.valueOf(i)));
System.out.println("loop "+i+" finish");
}
}
[/code]
结果可以看出来,并不是立即释放,而是由jvm自己去决定什么时候去释放
除非手动调用System.gc();
最好不要手动去释放
每次执行到这个循环的时候在堆中开辟内存,其引用被置于栈中提供高速访问。当局部变量一但脱离作用域,内存立即释放。希望对你有帮助。
恩,他没有引用了,jvm就会可能会回收它
java -XX:+PrintGCDetails YourClass
你执行下就看出来了
其实kidding87说的很对,就是kidding87给你的那段程序,其实你可以把那行“System.out.pringln”去掉,再用java -XX:+PrintGCDetails TestGc 去运行就会发现会有几次GC被执行。这是由一个专门负责GC的后台线程实现的,即使你显式调用了System.gc();也不能够完完全全保证GC会立即执行(要看JVM的运行情况),GC是由JVM来控制的。
每次循环,上次创建的List对象就失去了引用,等垃圾回收的时候会把这些没有引用的对象回收掉。
更细一点来说,当Eden区被占满的时候,就会触发一次minorGC。
楼主看了下面的程序就应该更了解了:
[code="java"]
public class Test1 {
static int i=1000;
public static void main(String[] args) {
while(i-->0){
List l = new ArrayList() {
@Override
/*该方法会在发生GC第一次扫描根集合对象的时候被调用,所以就是象征性地表示一下大概i的值是多少的时候会发生GC
*/
protected void finalize() throws Throwable {
if(i > 0)
System.out.println("i: " + i);
}
};
for(int j=0;j++<1000;l.add(Integer.valueOf(i)));
}
}
}
[/code]
编译之后使用java -XX:+PrintGCDetails -XX:+PrintHeapAtGC Test1来运行
我截一段小图给你,看看就明白了。
[img]http://dl.iteye.com/upload/picture/pic/111891/ded56266-c853-3f96-af7a-5c9cd7fc1a0e.png[/img]