OOM異常:OutOfMemoryError
1.JAVA堆溢出
JAVA堆用於存儲對象實例,只要不斷的創建對象,並且保證GC Roots到這些對象之間有路徑可以來避免垃圾回收機制清除這些對象,那么在對象數量達到最大堆的容量限制之后就會產生OOM異常
解決方案:先分析到底是出現了內存泄漏(無法釋放已申請的內存空間)還是內存溢出(沒有足夠的內存空間使用)
內存泄漏:通過工具查看泄漏對象到GC Roots的引用鏈,於是就能夠找到內存泄漏對象是通過怎樣的路徑與GC Roots相關聯並導致垃圾收集器無法回收,這樣就可以准確的定位到內存泄漏的代碼
內存溢出:檢查JVM的堆參數,與機器物理內存相比看看是否可以調大,並且從代碼上檢查是否存在某些對象生命周期太長,持有狀態時間太長等情況,減少程序運行期間內存的消耗
2.虛擬機棧和本地方法棧溢出
多線程環境下,當為每個線程分配的棧內存越大,就越容易產生內存溢出異常,因為操作系統分配給每個進程的內存是有限的,每個線程分配到的棧容量越大,可以建立的線程數量自然越少,建立線程就越容易把剩下的內存耗盡
解決方案:減少最大堆和減少棧容量來換取更多的線程
3.方法區和運行常量池溢出
運行常量池是方法區的一部分,方法區存放的是Class的相關信息,當運行時產生了大量的類了填滿方法區時,再產生類就會導致OOM
比如大量的JSP或動態產生JSP文件的應用(JSP第一次運行需要編譯為JAVA類),基於OSGI的應用(即同一個文件,被不同的類加載器加載也會視為不同的類)
解決方案:減少不必要的類的產生
4.本機直接內存溢出
物理機器內存不足,滿足不了JVM需求了
參考書籍:深入理解JAVA虛擬機 java高級特性與最佳實踐