我正在用 Java 及其允许内存泄漏的能力做一个小实验。我写了这个简单的代码:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
class Obj {
int i;
Obj(int i) {
this.i = i;
}
}
List<Obj> list;
while(true) {
list = new ArrayList<Obj>();
for(int i = 0; i < 1000; i++) {
Obj o = new Obj(i);
list.add(o);
}
try {
Thread.sleep(1); //<-- added to give the gc time to trash the previous iteration
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
执行此操作时(尤其是每次迭代都会将更多对象添加到列表中),您可以看到使用的内存量迅速增加。在每次迭代中添加 10000 个对象时,我能够非常快速地达到 2 GB。看起来好像列表(以及使用“链表”类似函数的其他类型的对象)不喜欢被删除。
当我没有将对象添加到列表中时,内存堆根本没有增加(这意味着垃圾处理正在完成它的工作)。我尝试将列表重置为 null 每次迭代然后重新声明它以及调用 clear() 方法。似乎没有任何效果。每当我在循环中使用 List 时,我的 RAM 都会呼救。
那么,为什么会出现这种情况?为什么垃圾处理不会在每次迭代时都摆脱列表而不是让它们堆积起来?List 接口不允许这种用法吗?我只是没有给垃圾处理足够的时间来摆脱最后一个实例吗?