一、產生內存溢出的
1、java.lang.OutofMemoryError:Java heap space
2、java.lang.OutofMemoryError:PermGen space
3、java.lang.OutofMemoryError:unable to create new native thread
4、java.lang.OutofMemoryError:GC overhead limit exceeded
1、Java堆空間不夠,當應用程序申請更多的內存,而Java堆內存已經無法滿足應用程序對內存的需要,將拋出這種異常。
2、Java永久代空間不夠,永久代中包含類的字節碼和長常量池,類的字節碼加載后的信息,這和存放對象實例的堆區是不同的,大多數JVM的實現都不會對永久帶進行垃圾回收,因此,只要類加載的過多就會出現這個問題。一般的應用程序都不會產生這個錯誤,然而,對於Web服務器來講,會產生有大量的JSP,JSP在運行時被動態的編譯成Java Servlet類,然后加載到方法區,因此,太多的JSP的Web工程可能產生這個異常。
3、本質原因是創建了太多的線程,而能創建的線程數是有限制的,導致了這種異常的發生。
4、是在並行或者並發回收器在GC回收時間過長、超過98%的時間用來做GC並且回收了不到2%的堆內存,然后拋出這種異常進行提前預警,用來避免內存過小造成應用不能正常工作。
下面兩個異常與OOM有關系,但是,又沒有絕對關系。
java.lang.StackOverflowError …
java.net.SocketException: Too many open files
1、是JVM的線程由於遞歸或者方法調用層次太多,占滿了線程堆棧而導致的,線程堆棧默認大小為1M。
2、是由於系統對文件句柄的使用是有限制的,而某個應用程序使用的文件句柄超過了這個限制,就會導致這個問題。
二、產生原因及解決辦法
【情況一】:
java.lang.OutOfMemoryError: Java heap space:這種是java堆內存不夠,一個原因是真不夠,另一個原因是程序中有死循環;
如果是java堆內存不夠的話,可以通過調整JVM下面的配置來解決:
< jvm-arg>-Xms3062m < / jvm-arg>
< jvm-arg>-Xmx3062m < / jvm-arg>
【情況二】
java.lang.OutOfMemoryError: GC overhead limit exceeded
【解釋】:JDK6新增錯誤類型,當GC為釋放很小空間占用大量時間時拋出;一般是因為堆太小,導致異常的原因,沒有足夠的內存。
【解決方案】:
1、查看系統是否有使用大內存的代碼或死循環;
2、通過添加JVM配置,來限制使用內存:
< jvm-arg>-XX:-UseGCOverheadLimit< /jvm-arg>
【情況三】:
java.lang.OutOfMemoryError: PermGen space:這種是P區內存不夠,可通過調整JVM的配置:
< jvm-arg>-XX:MaxPermSize=128m< /jvm-arg>
< jvm-arg>-XXermSize=128m< /jvm-arg>
【注】:
JVM的Perm區主要用於存放Class和Meta信息的,Class在被Loader時就會被放到PermGen space,這個區域成為年老代,GC在主程序運行期間不會對年老區進行清理,默認是64M大小,當程序需要加載的對象比較多時,超過64M就會報這部分內存溢出了,需要加大內存分配,一般128m足夠。
【情況四】:
java.lang.OutOfMemoryError: Direct buffer memory
調整-XX:MaxDirectMemorySize= 參數,如添加JVM配置:
< jvm-arg>-XX:MaxDirectMemorySize=128m< /jvm-arg>
【情況五】:
java.lang.OutOfMemoryError: unable to create new native thread
【原因】:Stack空間不足以創建額外的線程,要么是創建的線程過多,要么是Stack空間確實小了。
【解決】:由於JVM沒有提供參數設置總的stack空間大小,但可以設置單個線程棧的大小;而系統的用戶空間一共是3G,除了Text/Data/BSS /MemoryMapping幾個段之外,Heap和Stack空間的總量有限,是此消彼長的。因此遇到這個錯誤,可以通過兩個途徑解決:
1.通過 -Xss啟動參數減少單個線程棧大小,這樣便能開更多線程(當然不能太小,太小會出現StackOverflowError);
2.通過-Xms -Xmx 兩參數減少Heap大小,將內存讓給Stack(前提是保證Heap空間夠用)。
【情況六】:
java.lang.StackOverflowError
【原因】:這也內存溢出錯誤的一種,即線程棧的溢出,要么是方法調用層次過多(比如存在無限遞歸調用),要么是線程棧太小。
【解決】:優化程序設計,減少方法調用層次;調整-Xss參數增加線程棧大小
