在大学里,我们得到了以下代码示例,我们被告知,运行这段代码时会发生内存泄漏。该示例应证明这是垃圾收集器无法工作的情况。
就我的面向对象编程而言,唯一能够造成内存泄漏的代码行是
items=Arrays.copyOf(items,2 * size+1);
documentation说,元素被复制。这是否意味着引用已被复制(因此在堆上创建了另一个条目)或对象本身正在被复制?据我所知,Object 和 Object[] 是作为引用类型实现的。因此,为“items”分配一个新值将允许垃圾收集器发现旧的“item”不再被引用,因此可以被收集。
在我看来,此代码示例不会产生内存泄漏。有人能证明我错了吗? =)
import java.util.Arrays;
public class Foo
{
private Object[] items;
private int size=0;
private static final int ISIZE=10;
public Foo()
{
items= new Object[ISIZE];
}
public void push(final Object o){
checkSize();
items[size++]=o;
}
public Object pop(){
if (size==0)
throw new ///...
return items[--size];
}
private void checkSize(){
if (items.length==size){
items=Arrays.copyOf(items,2 * size+1);
}
}
}
最佳答案
pop 方法产生内存泄漏。
原因是您只是减少了队列中项目的数量,但实际上并没有将它们从队列中移除。引用保留在数组中。如果您不删除它们,即使生成该对象的代码已执行,垃圾收集器也不会破坏这些对象。
想象一下:
{
Object o = new Object();
myQueue.add(o);
}
现在您对该对象只有一个引用 - 数组中的一个。
稍后你会:
{
myQueue.pop();
}
此 pop 不会删除引用。如果您不删除该引用,垃圾收集器将认为您仍在考虑使用该引用并且该对象很有用。
因此,如果您用 n
个对象填充队列,那么您将持有这些 n
对象的引用。
这是您的老师告诉您的内存泄漏。
关于java - 为什么此代码示例会产生内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2843799/