问题描述
看代码while(...){ List list =new arraylist list.add();}请问进入下一次循环的时候 上一次循环产生的list能够被gc回收吗 问题补充:kidding87 写道
解决方案
上面的说的不对,回收不回收,jvm说了算,并不是立刻就回收jvm启动参数上加上gc的日志-XX:+PrintGCDetailspublic class TestGcpublic static void main(String[] args) {int i=1000;while(i-->0){List l = new ArrayList<Integer>();for(int j=0;j++<1000;l.add(Integer.valueOf(i)));System.out.println("loop "+i+" finish");}}结果可以看出来,并不是立即释放,而是由jvm自己去决定什么时候去释放除非手动调用System.gc();最好不要手动去释放
解决方案二:
其实kidding87说的很对,就是kidding87给你的那段程序,其实你可以把那行“System.out.pringln”去掉,再用java -XX:+PrintGCDetails TestGc 去运行就会发现会有几次GC被执行。这是由一个专门负责GC的后台线程实现的,即使你显式调用了System.gc();也不能够完完全全保证GC会立即执行(要看JVM的运行情况),GC是由JVM来控制的。每次循环,上次创建的List对象就失去了引用,等垃圾回收的时候会把这些没有引用的对象回收掉。更细一点来说,当Eden区被占满的时候,就会触发一次minorGC。楼主看了下面的程序就应该更了解了:public class Test1 {static int i=1000;public static void main(String[] args) {while(i-->0){List<Integer> l = new ArrayList<Integer>() {@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)));}}}编译之后使用java -XX:+PrintGCDetails -XX:+PrintHeapAtGC Test1来运行我截一段小图给你,看看就明白了。
解决方案三:
恩,他没有引用了,jvm就会可能会回收它java -XX:+PrintGCDetails YourClass你执行下就看出来了
解决方案四:
每次执行到这个循环的时候在堆中开辟内存,其引用被置于栈中提供高速访问。当局部变量一但脱离作用域,内存立即释放。希望对你有帮助。