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

Java 为什么这个程序会导致内存泄漏?,java,Java,嗯,我正在经历Java中的内存泄漏 我看过下面这个简单的程序,作者说 以下程序可能会导致内存泄漏 但是,请告诉我这个程序有什么问题,为什么可以 产生内存泄漏 package com.code.revisited.memoryleaks; public class StackTest { public static void main(String[] args) { Stack<Integer> s = new Stack<>(10000);

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

    }

}
package com.code.retrieved.memoryleaks;
公共类堆栈测试{
公共静态void main(字符串[]args){
堆栈s=新堆栈(10000);
对于(int i=0;i<10000;i++){
s、 推(i);
}
而(!s.isEmpty()){
s、 pop();
}
while(true){
//做点什么
}
}
}

pop
方法正在从
堆栈中删除
Integer
对象。但整数对象不被反引用;这意味着它们将占用内存

更新

有效Java的
第6项解释了这一点:消除过时的对象引用

如果堆栈先增长后收缩,则对象
从堆栈弹出的数据不会被垃圾收集,即使程序
使用堆栈时不再引用它们。这是因为堆栈保持
对这些对象的过时引用。过时的引用只是一个引用
这将永远不会被取消引用。


解决这类问题的方法很简单:清空引用或在对象过时后从堆栈中删除对象。在给定的情况下,pop方法将减少top引用。

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

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

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

--编辑--

你有没有从我这里拿这个例子?
如果是,请注意,正如我所怀疑的,它还包括一个堆栈实现。

您指的是前256个吗?或者什么?这没有什么意义,因为Java文档说它正在从堆栈顶部删除整数。因此,取消引用并不是真正必要的。但是我从来没有使用过
堆栈
,所以请详细说明以便我能理解:)我和Andy的想法一样,为什么需要取消引用??这个答案似乎没有任何意义。为什么它会被升级?可能是因为堆栈仍将占据某些位置,但这不是真正的“泄漏”。这不是内存泄漏。我想理想情况下,
堆栈
将进入一个范围,当您使用它时,它可以被GC处理,但这不是一个“泄漏”。如果您指的是,那么泄漏不在本例中,而是在
Stack.pop中。这部分没问题。是的,我从那里举了个例子,但我想产生内存泄漏。@Kiran:假设您依赖数组arr,并且您当前的顶级索引由j表示,您的pop方法可能应该执行以下操作:1)检查堆栈是否为空2)使用值arr[j]保存引用3)将null赋值给arr[j]4)返回引用