2010-10-19 465 views
2

http://www.ibm.com/developerworks/rational/library/05/0816_GuptaPalanki/#javaexamplejava中的內存泄露

整個代碼中的作者說有內存泄漏。

public class LeakExample { 
    static Vector myVector = new Vector(); 
    static HashSet pendingRequests = new HashSet(); 

    public void slowlyLeakingVector(int iter, int count) { 
     for (int i=0; i<iter; i++) { 
      for (int n=0; n<count; n++) { 
       myVector.add(Integer.toString(n+i)); 
      } 
      for (int n=count-1; n>0; n--) { 
       // Oops, it should be n>=0 
       myVector.removeElementAt(n); 
      } 
     } 
    } 

這段代碼是如何有內存泄漏,而下面沒有。什麼使兩者不同。

public void noLeak(int size) { 
     HashSet tmpStore = new HashSet(); 
     for (int i=0; i<size; ++i) { 
      String leakingUnit = new String("Object: " + i); 
      tmpStore.add(leakingUnit); 
     } 
     // Though highest memory allocation happens in this 
     // function, but all these objects get garbage 
     // collected at the end of this method, so no leak. 
    } 

回答

6

在您的第一個示例中,並非所有向量元素都被刪除(如代碼中的註釋所示)。而且,由於myVectorstatic成員變量,它在那裏停留,只要應用程序正在運行,並會隨時間增長與每次調用slowlyLeakingVector()

在第二示例中,tmpStore是局部變量,這將被垃圾收集每次從noLeak()返回後。

1

這裏的關鍵是

for (int n=count-1; n>0; n--) { 
    // Oops, it should be n>=0 
    myVector.removeElementAt(n); 
} 

最後一個元素永遠不會被作爲n刪除從未0內循環,即removeElementAt(0)從來沒有運行。這導致元素在載體中緩慢累積。

+0

感謝您的幫助 – John 2010-10-19 10:17:29

2

每個第一代碼運行,正被添加的元素,和(n-1)被刪除(在0的元素不是),所以矢量慢慢存儲永遠不會被使用的元件的時間。而且,由於矢量是靜態的,它將一直存在,直到JVM被關閉並泄漏內存。

在第二個例子中,tmpStore可以是在每次呼叫結束時收集的垃圾,所以沒有泄漏。

+0

感謝了很多這 – John 2010-10-19 10:40:39