OutOfMemoryError

Java堆溢出

Java堆用于存儲對象實例,只要不斷地創(chuàng)建對象,并且保證GC Roots到對象之間有可達路徑來避免垃圾回收機制清除這些對象,那么在對象數(shù)量到達最大堆的容量限制后就會產(chǎn)生內(nèi)存溢出異常。
要解決Java堆溢出異常,重點是確認異常源于內(nèi)存泄漏還是內(nèi)存溢出。

虛擬機棧和本地方法棧溢出

如果線程請求的棧深度大于虛擬機所允許的最大深度,將拋出StackOverflowError異常。
如果虛擬機在擴展棧時無法申請到足夠的內(nèi)存空間,則將拋出OutOfMemoryError異常。

在單個線程下,無論是由于棧太大還是虛擬機棧容量太小,當內(nèi)存無法分配的時候,虛擬機拋出的都是StackOverflowError異常。

多線程情況下,通過不斷地建立線程的方式可以產(chǎn)生OutOfMemoryError異常,如果不能減少線程數(shù)或者更換64位虛擬機的情況下,只能通過減少最大堆和棧容量來換取更多線程。

StackOverflowError異常有錯誤堆棧可以閱讀。

方法區(qū)和運行時常量池溢出(Non-Heap)

我們可以通過-XX:PermSize=128m -XX:MaxPermSize=256m限制方法區(qū)大小,從而間接限制其中容量池的容量

當前的很多主流框架,如spring、hibernate,在對類進行增強時,都會使用到CGLib這類字節(jié)碼技術,增強的類越多,就需要越大的方法區(qū)來保證動態(tài)生成的Class可以加載如內(nèi)存。

在經(jīng)常生成大量class的應用中,需要特別注意類的回收情況。這類場景除了CGLib字節(jié)碼增強和動態(tài)語言外,常見的還有大量JSP或動態(tài)產(chǎn)生JSP文件的應用、基于OSGI的應用等。

本機直接內(nèi)存溢出

DirectMemory容量可通過-XX:MaxDirectMemorySize指定,如果不指定,則默認與Java堆最大值一樣。

由DirectMemory導致的內(nèi)存溢出,一個明顯的特征是在Heap Dump文件中不會看見明顯的異常,如果讀者發(fā)現(xiàn)OOM之后Dump文件很小,而程序中又直接或間接使用了NIO,那就可以考慮檢查一下是不是這方面的原因。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容