1、Java堆溢出:heap
Java堆內存主要用來存放運行過程中所以的對象,該區域OOM異常一般會有如下錯誤信息;
java.lang.OutofMemoryError:Java heap space
此類錯誤一般通過Eclipse Memory Analyzer分析OOM時dump的內存快照就能分析出來,到底是由於程序原因導致的內存泄露,還是由於沒有估計好JVM內存的大小而導致的內存溢出。
-Xms:初始堆大小,默認值為物理內存的1/64(<1GB),默認(MinHeapFreeRatio參數可以調整)空余堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制.
-Xmx:最大堆大小,默認值為物理內存的1/4(<1GB),默認(MaxHeapFreeRatio參數可以調整)空余堆內存大於70%時,JVM會減少堆直到 -Xms的最小限制
-Xmn:年輕代大小(1.4or lator),此處的大小是(eden + 2 survivor space),與jmap -heap中顯示的New gen是不同的。
2、棧溢出:stack
棧用來存儲線程的局部變量表、操作數棧、動態鏈接、方法出口等信息。如果請求棧的深度不足時拋出的錯誤會包含類似下面的信息:
java.lang.StackOverflowError
另外,由於每個線程占的內存大概為1M,因此線程的創建也需要內存空間。操作系統可用內存-Xmx-MaxPermSize即是棧可用的內存,如果申請創建的線程比較多超過剩余內存的時候,也會拋出如下類似錯誤:
java.lang.OutofMemoryError: unable to create new native thread
相關的JVM參數有:-Xss: 每個線程的堆棧大小,JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K.
在相同物理內存下,減小這個值能生成更多的線程.但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在3000~5000左右。
3、運行時常量溢出 constant
運行時常量保存在方法區,存放的主要是編譯器生成的各種字面量和符號引用,但是運行期間也可能將新的常量放入池中,比如String類的intern方法。
如果該區域OOM,錯誤結果會包含類似下面的信息:
java.lang.OutofMemoryError: PermGen space
相關的JVM參數有:
-XX:PermSize:設置持久代(perm gen)初始值,默認值為物理內存的1/64
-XX:MaxPermSize:設置持久代最大值,默認為物理內存的1/4
4、方法區溢出 directMemory
方法區主要存儲被虛擬機加載的類信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。理論上在JVM啟動后該區域大小應該比較穩定,但是目前很多框架,比如Spring和Hibernate等在運行過程中都會動態生成類,因此也存在OOM的風險。
如果該區域OOM,錯誤結果會包含類似下面的信息:
java.lang.OutofMemoryError: PermGen space
相關的JVM參數可以參考運行時常量。
另外,在定位JVM內存問題的時候可以借助於一些輔助信息:
1、日志相關-XX:+PrintGC:輸出形式:
[GC 118250K->113543K(130112K), 0.0094143 secs]
[Full GC 121376K->10414K(130112K), 0.0650971 secs]
-XX:+PrintGCDetails:輸出形式:
[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]
[GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
-XX:+PrintGCTimeStamps:打印GC停頓耗時
-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期間程序暫停的時間.
-XX:+PrintHeapAtGC:打印GC前后的詳細堆棧信息
-Xloggc:filename:把相關日志信息記錄到文件以便分析.
2、錯誤調試相關:
-XX:ErrorFile=./hs_err_pid<pid>.log:如果JVM crashed,將錯誤日志輸出到指定文件路徑。
-XX:HeapDumpPath=./java_pid<pid>.hprof:堆內存快照的存儲文件路徑。
-XX:-HeapDumpOnOutOfMemoryError:在OOM時,輸出一個dump.core文件,記錄當時的堆內存快照
3、類裝載相關
-XX:-TraceClassLoading:打印class裝載信息到stdout。記Loaded狀態。-XX:-TraceClassUnloading:打印class的卸載信息到stdout。記Unloaded狀態。
