2013-10-28 76 views
3

我試圖使用的LinkedHashMap作爲本地FIFO緩存解決方案覆蓋它removeEldestEntry方法,以保持大小固定:固定大小LinkedHashMap內存泄漏?

Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, .75F, false) { 
    protected boolean removeEldestEntry(Map.Entry eldest) { 
     return size() > MAX_CACHE_SIZE; 
    } 
}; 

,但是當我不斷地添加新條目到地圖監控進程內存我看到它不斷增長,直到雖然地圖大小不會增加,但會使用最大虛擬機內存。

是否由設計?爲什麼需要更多的內存,如果舊的值被丟棄,地圖的大小是有限的?

UPDATE: 的要求,我附上全碼:

@Test 
public void mapMemory() { 
    final int MAX_CACHE_SIZE = (int) 1E3; 
    Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, 1F, false) { 
     protected boolean removeEldestEntry(Map.Entry eldest) { 
      return size() > MAX_CACHE_SIZE; 
     } 
    }; 

    for (long i = 0; i < 1E10; i++) { 
     lhm.put("key_" + i, "VALUE"); 
    } 
} 
+0

爲什麼不使用一個實際的FIFO數據結構,而不是試圖模仿一個用一個HashMap? – GordonM

+0

我需要它能夠通過鍵檢索值。什麼是FIFO解決方案? – wziska

回答

0

在構造函數的第二個參數定義loadFactor,乘以你的第一個參數(地圖大小),它給你的值(大小)觸發你地圖的大小調整。所以你的情況,你應該(可能)使用loadFactor = 1

編輯:
你的內存泄漏是由東西,你不給我們造成的,如上面的代碼將永遠不會導致內存泄漏。
檢查您可能在哪裏保留對舊值/對象的引用。地圖本身不會導致內存泄漏 - 如果它確實使用地圖的所有系統(並且有很多地圖)每隔幾個小時就會崩潰。

+0

不起作用。正如我在問題中所描述的那樣,地圖大小不會增加。但內存使用確實如此。 – wziska

+0

地圖大小調整後,會增加容量,而不是大小。該值是調整地圖大小時的觸發點。在調整大小時,地圖會保留更多內存以便稍後使用。默認的增量因子是2,因此內存使用量(幾乎)翻了一番。 –

+1

順便說一句:什麼「不起作用」,以什麼方式?如果它是你的電視「不起作用」,那麼我將無法幫助你 - 太遠 –

0

如果您需要隨機訪問集合的內容,那麼它不是一個真正的FIFO。

應該注意的是,雖然集合不存儲對象,但它們存儲對象的引用,這是一個重要的區別。將相同的對象存儲在2個不同的集合中將不會產生大量的內存開銷,因此可能您最好的解決方案是將同一對象存儲到隊列和映射中,當您需要隨機訪問時需要FIFO行爲時使用隊列。

儘管如此,您必須記得從兩個集合中刪除對象,否則它不會被GC'd。

+0

好的,我可以考慮使用兩種結構編寫我自己的實現。 但是我真的需要它,如果有問題我已經提供瞭解決方案嗎?我只想知道這種廣泛的內存使用情況是否應該擔心。 – wziska

+0

擁有一個能夠處理所有這些問題的類將更符合良好的面向對象,因爲您可以在其他項目中重用它。 – GordonM