0

好吧,我正在经历 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
        }

    }

}
4

2 回答 2

1

pop方法是IntegerStack. 但是 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 中删除对象。在给定的情况下,pop 方法将减少顶部引用。

于 2013-04-07T17:37:21.077 回答
0

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

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

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

- 编辑 -

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

于 2013-04-07T17:52:50.277 回答