JVM總結-OutOfMemoryError異常

在JVM規範中,除了程序計數器,虛擬機內存的其餘幾個運行區域都有可能發生OutOfMemoryError異常。java

Java堆溢出:

Java堆是用來存儲對象實例,只要不停地建立對象實例,而且讓GC ROOTS到對象之間有可達路徑來避免垃圾回收機制清除這些對象,當對象數量達到最大堆的容量限制就會產生內存溢出的異常。框架

經過設置JVM參數-XX:+HeapDumpOnOutOfMemoryError能夠讓JVM在發生內存泄露異常Dump出當前內存堆轉儲快照方便後面分析。默認狀況下,堆內存快照會保存在JVM的啓動目錄下名爲java_pid<pid>.hprof 的文件裏(在這裏<pid>就是JVM進程的進程號)工具

當堆內存溢出時,會在異常信息後提示Java heap spacespa

使用內存映像分析工具進行分析,判斷是內存溢出仍是內存泄露操作系統

一、內存泄露:3d

經過工具查看泄露對象到GC ROOTS引用鏈。就能夠找到泄露對象是經過怎樣的路徑與GC ROOTS相關聯,致使垃圾收集器沒法自動回收他們對象

二、內存溢出:blog

檢查虛擬機的堆參數,看是否還能夠調大,從代碼上檢查某些對象生命週期過長,持有時間過長的狀況。生命週期

例子:進程

使用JProfiler

一、打開快照文件

二、查看佔用內存較大的對象

 

二、查看該對象經過怎樣的路徑與gc roots相關聯

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

在HotSpot中是不區分虛擬機棧和本地方法棧的,虛擬機在擴展棧時沒法分配到足夠的內存空間就會拋出OutOfMemoryError。

方法區和運行時常量池溢出

運行時常量池溢出,錯誤後緊跟PermGen space說明運行時常量池屬於方法區的一部分。

運行時產生大量的類可能填滿方法區,如一些框架使用CGLib這類字節碼技術,加強的類越多,就須要越大的方法區來保證動態生成的Class能夠加載進內存

本機直接內存溢出

在Heap Dump中不會出現明顯的異常,能夠考慮是這個狀況DirectByteBuffer直接經過反射獲取Unsafe實例進行內存分配,會拋出內存溢出異常,可是他拋出的異常沒有真正向操做系統申請分配內存,而是經過計算得知內存沒法分配。

相關文章
相關標籤/搜索