2011-08-19 37 views
2

我正在研究一個應用程序,它將大量數據從數據庫讀入到Map<String,Map<String,Map<String,String>>>中,對其進行處理,並使用內部xml編寫器將處理後的報告寫入電子表格。整個運行可能需要大約12個小時。使用HashMap進行Java存儲器管理

我發現我越來越

Exception in thread "CursorController-Thread-0" java.lang.OutOfMemoryError: Java heap space 
    at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:45) 
    at java.lang.StringBuilder.<init>(StringBuilder.java:68) 

當我試圖寫這個巨型文件。出於這個原因,我認爲最好是在完成處理時寫出每個Map<String,Map<String,String>>(注意更深一層)。

我的問題是,我怎麼能確保Map<String,Map<String,String>>沒有保留在內存中,因爲地圖>>仍然包含它?

回答

7

一旦你用密鑰"key"映射到Map<String,Map<String,String>>做你根本

hugeMap.remove("key"); 

這將「空」出在hugeMap項,使Map<String,Map<String,String>>符合垃圾收集(即從不成爲造成堆空間不足的部分)。

+0

正是我在找的!感謝您的快速回答。 –

+0

沒問題,不客氣。 – aioobe

2

我會爲這類問題選擇不同的解決方案。處理源數據需要12個小時。

您是否考慮過任何可擴展的解決方案?對於例如Hadoop的?

+0

另一個解決方案可能是SpringBatch。 –

+0

我很樂意使用類似這樣的解決方案,但這是一位中級經理想要的報告。整個部門只有大約20臺電腦,並且他們被工程工作佔用。 儘管比單個工作站處理數以百萬計的行更可伸縮的解決方案是最好的!對我來說不可能。 –

+0

你並不需要那麼多的電腦。 MapReduce方法也可以提供幫助。 –

-1

你不能。

垃圾回收器每當它喜歡就運行,並釋放它喜歡的任何東西。

也就是說,值得一試的是,在刪除對不再需要的數據的所有引用後,請致電System.gc()

無論如何,你已經寫道寫入數據時內存不足錯誤。也許你有一個內存泄漏。

0

在您的Map>>上使用map.remove(key)方法。你可以不定期打電話System.gc();強制垃圾收集。

+2

'系統。gc'不會強制垃圾回收。它會*提示JVM,它可能是運行GC的好主意。 – aioobe

+0

你是對的:http://download.oracle.com/javase/1.4.2/docs/api/java/lang/System.html#gc%28%29。謝謝。 – mradu

0

如果你想保留你的結構,你可以保留寫在外層地圖上的地圖>。但可能你應該清除它的內容,以便它是空的。另外,確保在處理它並編寫它時,在清除內容之前,不要在任何地方保留對其成員(映射)的引用。請參閱以下文章以選擇最適合您需求的方法Using .clear() or letting the GC take care of it