區域 | 作用 | 異常 | 控制參數 | 解決思路 |
java堆 | 存放對象的實例。 | java.lang.OutOfMemory Error:Java heap space | -Xms(初始化堆), -Xmx(最大堆), -Xmn(新生代) |
1、先查看是不是內存泄漏(內存中的對象是不是必須的),如果是泄漏,則找到與GC root 的路徑解決泄漏。 2、看物理內存是否允許加大-Xms,-Xmx。 3、檢查堆中是不是有對象實例一直在內存中沒有釋放。 4、技巧讓-Xms = -Xmx,減少內存擴展的開銷。 |
虛擬機棧和本地方法棧 | 控制方法的執行。 | 如果線程請求的棧深度大於虛擬機所允許的最大深度:java.lang.StackOverflow Error 如果續集你在擴展棧時無法申請到足夠的內存空間: java.lang.OUtOfMemory Error |
-Xss | 1、加大-Xss參數。 2、減少線程。 3、更換64位虛擬機。 4、減少最大堆(Xmx)。 |
方法區 | 用於存放Class的相關信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。 | java.OutOfMemory Error:PermGen space | -XX:PermSize -XX:MaxPermSize |
這是最常見的內存溢出異常。 1、加大參數(治標不治本)。 2、增加參數:-XX:PrintGCDetails,-XX:+PrintGCTimeStamps和-XX:+PrintGCDateStamps,還可以指定日志輸出到文件:-Xloggc:<fileName>。通過查看GC日志來查看新生代GC(Minor GC)和老年代GC(Full GC或MajorGC)的回收效率和回收頻率。通常Minor GC會很頻繁,回收效率高才是對。 3、稍微的加大Survivor1 Survivor2的空間。 |
本機直接內存 | 如NIO,就是直接通過此內存實現。 | java.lang.OutOfMemory Error,有 allocate、Native字樣 |
-MaxDirectMemorySize 如不指定則與-Xmx一致。 |
合理規划服務器內存,預留足夠的內存給本地內存。加大參數。 |
空間關系:
java堆 = 新生代 + 老年代。
新生代 = Eden(伊甸園) + Survivor1 + Survivor2。
大多數情況下,對象在新生代Eden區中分配。當Eden中沒有足夠的空間時,就觸發一次Minor GC。Survivor2 是Minor GC時用於復制用的。當發生Minor GC時如果發現所要輔助的對象(活着的對象)無法存放到Survivor2中,則通過分配擔保機制提前轉移到老年代中去。
如配置-Xms20M,-XMx20M,-Xmn10M,-XX:SurvivorRatio=8。
含義:java堆大小為20M,不可擴展,其中10MB分配給新生代,剩下的10MB分給老年代。-XX:SurvivorRatio=8 表示新生代中Eden區與其中一個Survivor區的空間比例為8:1。即 eden space 8192k,from space 1024k,to space 1024k。新生代總可用空間為9216kb(Eden區+1個Survivor區的總量)。
我們公司centos6.8 ,100G的內存,配置如下:
JAVA_OPTS="-Xms8g -Xmx8g -XX:ParallelGCThreads=8 -XX:PermSize=2g -XX:MaxPermSize=4g -Xss512k -Xmn6g -XX:-DisableExplicitGC -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled"
CATALINA_OPTS="-Xms8g -Xmx8g -XX:ParallelGCThreads=8 -XX:PermSize=2g -XX:MaxPermSize=4g -Xss512k -Xmn6g -XX:-DisableExplicitGC -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled"
版權聲明:本文只作者原創,轉文請注明出處。