我无法理解为什么此代码中没有OutOfMemoryError
public static void main(String[] args) {
Object[] ref = new Object[1];
while (true) {
ref[0] = new Object[]{ref};
ref = (Object[]) ref[0];
}
}
至于我,上面提到的代码必须按以下方式工作:
Start:
ref = new Object[1];
Loop:
ref[0] = new Object []{ new Object[1] }
ref = new Object []{ new Object[1] }
ref[0] = new Object []{ new Object []{ new Object[1] } }
ref = new Object []{ new Object []{ new Object[1] } }
我的意思是保存每个新Object的链接,垃圾收集器不能删除未使用的对象,因此必须有OutOfMemoryError。但如果代码运行,它将工作年龄......
我不明白或我错在哪里?请解释一下。
答案 0 :(得分:7)
此处没有内存泄漏。
考虑以下步骤:
Object[] ref = new Object[1];
ref --> array 1
ref[0] = new Object[]{ref};
ref --> array 1 --> array 2 --> array 1
ref = (Object[]) ref[0];
ref --> array 2 --> array 1 --> array 2 --> ...
ref[0] = new Object[]{ref};
ref --> array 2 --> array 3 --> array 2 --> ...
array 1
不再被引用,因此可以进行GC收集。 ref = (Object[]) ref[0];
ref --> array 3 --> array 2 --> array 3 --> ...
ref[0] = new Object[]{ref};
ref --> array 3 --> array 4 --> array 3 --> ...
array 2
不再被引用,因此可以进行GC收集。 ......循环继续。在每个循环之后,有一个不再引用的数组,它有资格进行垃圾回收。只要GC完成其工作,您就永远不会耗尽内存。
编辑:更正了数组在内存中的链接方式。感谢Javier指出这一点。
答案 1 :(得分:0)
Start:
ref = new Object[1];
Loop:
ref[0] = new Object []{ new Object[1] }
ref = new Object []{ new Object[1] }
// at this point ref is re-allocated
ref[0] = new Object []{ new Object []{ new Object[1] } }
ref = new Object []{ new Object []{ new Object[1] } }
// at this point ref is re-allocated
上述两个点ref
正在重新分配,因此先前ref
的引用将丢失。由于ref
丢失,这意味着java垃圾收集器已准备好取消引用前一个ref
指向的内存。