2013-04-07 122 views
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 
     } 

    } 

} 
+1

這可能是因爲堆棧仍然會佔用一些位置,但這不是真正的「泄漏」。 – 2013-04-07 17:38:26

+0

這不是內存泄漏。我想理想的情況是'Stack'會進入一個範圍,當你完成它時它可以被GC'd,但這不是一個「泄漏」。 – 2013-04-07 17:39:05

+1

如果你指的是http://coderevisited.com/memory-leaks-in-java/,那麼泄漏不在這個例子中,而是在'Stack.pop'中。這部分是好的。 – zch 2013-04-07 17:41:27

回答

1

這實際上取決於堆棧的實現方式。

如果這是Java的堆棧(java.util.Stack),那麼它不應該發生。底層數組是動態的,可能有未使用的插槽,但是在彈出項目時顯式設置爲空。

我猜你的例子中的堆棧不是標準堆棧;這可能是該示例的一部分,它說明了這種內存泄漏。例如,如果pop()方法減少底層數組索引,但不將數組項設置爲空,那麼上面的代碼應該在堆中留下1000個活動對象,儘管程序可能不再需要它們。

- 編輯 -

你接受來自http://coderevisited.com/memory-leaks-in-java/的例子嗎? 如果是這樣,請注意,它也包含堆棧實現,就像我懷疑的那樣。

+0

是的,我從那裏拿了一個例子,但我想產生內存泄漏。 – Kiran 2013-04-07 17:58:27

+0

@Kiran:假設你依賴一個數組arr,並且你的當前頂部索引用j表示,你的pop方法可能應該做如下操作:1)檢查堆棧是否爲空2)用值arr保存一個引用[j] 3)給arr [j]分配null 4)返回參考 – 2013-04-07 17:59:39

+0

明白了,非常感謝。 – Kiran 2013-04-07 18:00:33

1

pop方法是從Stack除去Integer對象。但是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上移除在給定的情況下,彈出方法會減少頂部參考。

+0

你是指第256個?或者是什麼 ? – 2013-04-07 17:37:56

+1

這並沒有什麼意義,因爲Java文檔說它會從棧頂移除整數。所以解引用並不是必須的。但我從來沒有使用'堆棧',所以請詳細說明,這樣我就可以理解:) – Andy 2013-04-07 17:41:16

+0

我認爲和安迪一樣,爲什麼需要解引用? – Kiran 2013-04-07 17:42:34