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