引起內存溢出的原因有很多種,常見的有以下幾種: 1.內存中加載的數據量過於龐大,如一次從數據庫取出過多數據; 2.集合類中有對對象的引用,使用完后未清空,使得JVM不能回收; 3.代碼中存在死循環或循環產生過多重復的對象實體; 4.使用的第三方軟件中的BUG; 5.啟動參數內存值設定的過小;
1.堆 設置jvm值的方法是通過-Xms(堆的最小值),-Xmx(堆的最大值) 2.棧 設置棧大小的方法是設置-Xss參數 3.PermGen space 第三個異常是關於perm的異常內容,我們需要的是設置方法區的大小,實現方式是通過設置-XX:PermSize和-XX:MaxPermSize參數 4.DirectMemory 第四個異常估計遇到的人就不多了,是DirectMemory內存相關的
DirectMemoruSize可以通過設置 -XX:MaxDirectMemorySize參數指定容量大小,如果不指定的話,那么就跟堆的最大值一致
內存使用監控工具jvmstat
解決辦法:
【情況一】: java.lang.OutOfMemoryError:Javaheapspace:這種是java堆內存不夠,一個原因是真不夠(如遞歸的層數太多等),另一個原因是程序中有死循環; 如果是java堆內存不夠的話,可以通過調整JVM下面的配置來解決: -Xms3062m -Xmx3062m
【情況二】 java.lang.OutOfMemoryError:GCoverheadlimitexceeded 【解釋】:JDK6新增錯誤類型,當GC為釋放很小空間占用大量時間時拋出;一般是因為堆太小,導致異常的原因,沒有足夠的內存。 【解決方案】: 1、查看系統是否有使用大內存的代碼或死循環; 2、通過添加JVM配置,來限制使用內存: -XX:-UseGCOverheadLimit
【情況三】: java.lang.OutOfMemoryError:PermGenspace:這種是P區內存不夠,可通過調整JVM的配置: -XX:MaxPermSize=128m -XXermSize=128m 【注】: JVM的Perm區主要用於存放Class和Meta信息的,Class在被Loader時就會被放到PermGenspace,這個區域成為年老代,GC在主程序運行期間不會對年老區進行清理,
默認是64M大小,當程序需要加載的對象比較多時,超過64M就會報這部分內存溢出了,需要加大內存分配,一般128m足夠。
【情況四】: java.lang.OutOfMemoryError:Directbuffermemory 調整-XX:MaxDirectMemorySize=參數,如添加JVM配置: -XX:MaxDirectMemorySize=128m
【情況五】: java.lang.OutOfMemoryError:unabletocreatenewnativethread 【原因】:Stack空間不足以創建額外的線程,要么是創建的線程過多,要么是Stack空間確實小了。 【解決】:由於JVM沒有提供參數設置總的stack空間大小,但可以設置單個線程棧的大小;而系統的用戶空間一共是3G,
除了Text/Data/BSS/MemoryMapping幾個段之外,Heap和Stack空間的總量有限,是此消彼長的。因此遇到這個錯誤,
可以通過兩個途徑解決:1.通過-Xss啟動參數減少單個線程棧大小,這樣便能開更多線程(當然不能太小,太小會出現StackOverflowError);
2.通過-Xms-Xmx兩參數減少Heap大小,將內存讓給Stack(前提是保證Heap空間夠用)。
【情況六】:
java.lang.StackOverflowError
【原因】:這也內存溢出錯誤的一種,即線程棧的溢出,要么是方法調用層次過多(比如存在無限遞歸調用),要么是線程棧太小。
【解決】:優化程序設計,減少方法調用層次;調整-Xss參數增加線程棧大小