tomcat總是卡死,查看日志catalina.out 發現瘋狂報錯
如下,提示內存溢出
java.lang.OutOfMemoryError: Java heap space
此外常見的內存溢出有以下兩種:
java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: Java heap space
解決方法:手動設置Heap size
Linux下的tomcat:
需要找到catalina.sh,在 cygwin=false 的上面一行加上:
JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m"
分析
-Xms 為jvm啟動時分配的初始內存 比如-Xms200m,表示分配200M -Xmx 為jvm運行分配的最大內存 比如-Xms500m,表示jvm進程最多只能夠占用500M內存
-Xss 每個線程堆棧的大小 一般情況下256K是足夠了。影響了此進程中並發線程數大小
-XX PermSize=64M JVM初始分配的非堆內存
-XX MaxPermSize=128M JVM最大允許分配的非堆內存,按需分配
首先了解一下JVM內存管理的機制,然后再解釋每個參數代表的含義。
1)堆(Heap)和非堆(Non-heap)內存
按照官方的說法:“Java 虛擬機具有一個堆,堆是運行時數據區域,所有類實例和數組的內存均從此處分配。堆是在 Java 虛擬機啟動時創建的。”
“在JVM中堆之外的內存稱為非堆內存(Non-heap memory)”。
簡單來說堆就是Java代碼可及的內存,是留給開發人員使用的;非堆就是JVM留給自己用的
所以方法區、JVM內部處理或優化所需的內存(如JIT編譯后的代碼緩存)、每個類結構(如運行時常數池、字段和方法數據)以及方法和構造方法的代碼都在非堆內存中。
堆內存分配
JVM初始分配的堆內存由-Xms指定,默認是物理內存的1/64;
JVM最大分配的堆內存由-Xmx指定,默認是物理內存的1/4。
默認空余堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;
空余堆內存大於70%時,JVM會減少堆直到-Xms的最小限制。
因此服務器一般設置-Xms、-Xmx 相等以避免在每次GC 后調整堆的大小。
說明:如果-Xmx 不指定或者指定偏小,應用可能會導致java.lang.OutOfMemory錯誤,此錯誤來自JVM,不是Throwable的,無法用try...catch捕捉。
非堆內存分配
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;
由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
XX:MaxPermSize設置過小會導致java.lang.OutOfMemoryError: PermGen space 就是內存益出。
說說為什么會內存益出:
(1)這一部分內存用於存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和存放Instance的Heap區域不同。
(2)GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS 的話,就很可能出現PermGen space錯誤。
這種錯誤常見在web服務器對JSP進行pre compile的時候
