为什么这个程序会导致内存泄漏?

时间:2013-04-07 17:35:34

标签: java

好吧,我正在通过Java中的内存泄漏。

我看到了这个简单的下面的程序,作者说 下面的程序可以使用内存泄漏

但请告诉我这个程序有什么问题以及为什么会这样 产生内存泄漏??

package com.code.revisited.memoryleaks;


public class StackTest {

    public static void main(String[] args) {
        Stack<Integer> s = new Stack<>(10000);
        for (int i = 0; i < 10000; i++) {
            s.push(i);
        }

        while (!s.isEmpty()) {
            s.pop();
        }

        while(true){
            //do something
        }

    }

}

2 个答案:

答案 0 :(得分:1)

pop方法正在从Integer中移除Stack个对象。但是Integer对象没有被引用;这意味着他们将占据记忆。

<强>更新

Item 6 of Effective Java中解释了这一点:消除过时的对象引用

If a stack grows and then shrinks, the objects that were popped off the stack will not be garbage collected, even if the program using the stack has no more references to them. This is because the stack maintains obsolete references to these objects. An obsolete reference is simply a reference that will never be dereferenced again.

解决此类问题的方法很简单:将引用置空或在Stack过时后从Stack中删除对象。在给定的情况下,pop方法将减少顶部引用。

答案 1 :(得分:1)

这实际上取决于堆栈的实现方式。

如果这是Java的堆栈(java.util.Stack),那么它不应该发生。底层数组是动态的,可能有未使用的插槽,但在弹出项时它们显式设置为null。

我猜你的例子中的堆栈不是标准堆栈;它可能是示例的一部分,它说明了这种内存泄漏。例如,如果pop()方法减少了底层数组索引,但没有将数组项设置为null,那么上面的代码应该在堆中留下1000个活动对象,尽管程序可能不再需要它们。

- 编辑 -

您是否从http://coderevisited.com/memory-leaks-in-java/中提取了示例? 如果是这样,请注意它还包括堆栈实现,就像我怀疑的那样。