出現java.lang.OutOfMemoryError: Java heap space的錯誤要麼是程序問題,要麼就是分配給JVM的內存確實不夠。
一般來說都是可以事前可控解決的。
但是如果不可控的情況,例如使用第三方包,或者系統抽筋,就會拋出OutOfMemoryError錯誤。OH NO,根據不會拋出來,當前線程直接掛掉。
既然都掛掉了,談什麼恢復?而且掛掉也不只是OutOfMemoryError的問題。
一般情況下,OutOfMemoryError在不可控的情況下,真的真的真的不需要處理,乾脆無視好了,就當是運氣好吧。而且解決起來,程序邏輯很難看。
如果你想較真,出現OutOfMemoryError時想死得好看一點,或者恢復起來優雅一點,那繼續。
先了解OutOfMemoryError的一些特點:
1,不確定不可控性。相信可控的情況你已經解決了。
2,不會拋出異常,也就是說try...catch不起作用。
3,出現後,當前線程就會掛掉。
4,對3點,如果在try...finally裏發生OutOfMemoryError,則會執行finally語句再掛掉。但不要以爲try...finally是萬能的,什麼情況都能得到執行,你用exit或者關機試試。
5,對3點,如果是多線程中的一個子線程(非守護),掛掉不影響其它線程,並且內存很快(是很快,就是很快)可以回收。
所以在你確定會遇到OutOfMemoryError但無法解決的時候,try...finally是有用的,只要不再做很多內存的操作吧,想繼續什麼流程都沒什麼問題(我沒遇到有問題的情況而已)。退出是必然的,finally裏還是需要善後,記錄狀態等。還要記得用無關要緊的獨立的線程去處理,最後通過守護程序,監控程序或者定時器重新啓動一個處理線程就是了。
====後記====
這幾天用TIKA抽取文檔內容並做索引,在抽取某個才40M(其它上百M以上的都沒有問題)的文檔時出現OutOfMemoryError,內存一下就用完了,加大到系統的上限也沒用,照樣完了,所以執行會停止。文檔是不停地增加,並要抽取內容做好索引,爲了使程序能順利不停地執行,所以有了上面的探索。