天天看點

java.lang.OutOfMemoryError: Java heap space的解決辦法

Java堆記憶體的OutOfMemory異常是實際應用中比較普遍的記憶體溢出情況。本文是我總結的解決這種問題的一些淺見,歡迎各位拍磚..

關于OutOfMemoryError的解決辦法網上的讨論也有很多,表面原因是堆記憶體不夠用.但是深層原因可以分為兩類,

一是記憶體溢出,二是記憶體洩漏.。

第一種情況比較簡單,解決方法是通過優化Java的堆參數-Xmx, -Xms來解決問題,這裡有具體做法。

http://www.blogjava.net/liuwentao253/archive/2008/06/03/205466.html

第二種就稍微複雜一些了,如果還想通過以上的方法來解決問題,最終的結果往往是治标不治本。

解決這種問題一般的手段是通過記憶體映像分析工具來對heapdump進行分析。heapdump檔案是記憶體的快照,說白了就是某一時間點記憶體的使用情況.分析記憶體的目的是确定是否有記憶體洩漏發生.

首先,要做的是設定參數,以期獲得heapdump檔案. 具體怎麼設定就不說了,可以參考這裡 http://44424742.iteye.com/blog/1063522

然後,你要做的就是重制題目所說的這種問題,出現OutOfMemoryError時,這時如果第一步設定正确,就可以得到相應的heapdump檔案了,恭喜你,成功了一半了!

第三步也是相當重要的一步,用記憶體分析軟體來打開得到的檔案,這種軟體也有很多,筆者用的是IBM的heap analyzer.不過用記憶體分析軟體要求你的記憶體必須大到足夠可以載入heapdump檔案。

最後就是分析heapdump檔案,這就要求你對資料結構和代碼本身的了解有相當的功底。舉個例子來說,之前分析了一個heapdump檔案,發現超過60%的記憶體被一個Cache連結清單占用,然後回到代碼發現在loadCache同時load到了一個hashmap和一個連結清單,而清空時隻清空了hashmap,反複的clear->load->clear導緻連結清單不斷的膨脹,直到OOM異常發生.

當然這種分析heapdump的方法也可能會發現記憶體中的對象還存活着,沒有記憶體洩漏,那就要深入代碼,檢查是否某些對象生命周期過長,長時間持有記憶體的情況,從根本上優化代碼.

繼續閱讀