鳥(niǎo)欲高飛先振翅,人求上進(jìn)先讀書(shū)。本文是原書(shū)的第9章 線程的監(jiān)控及其日常工作中如何分析里的9.3.3節(jié)常見(jiàn)的內(nèi)存溢出的三種情況。
3. 常見(jiàn)的內(nèi)存溢出的三種情況:
1)JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap space
JVM在啟動(dòng)的時(shí)候會(huì)自動(dòng)設(shè)置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等選項(xiàng)可進(jìn)行設(shè)置。Heap的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的時(shí)間是用于GC,且可用的Heap size 不足2%的時(shí)候?qū)伋龃水惓P畔ⅰ?/span>
解決方法:手動(dòng)設(shè)置JVM Heap(堆)的大小。
2)PermGen space溢出: java.lang.OutOfMemoryError: PermGen space
PermGen space的全稱(chēng)是Permanent Generation space,是指內(nèi)存的永久保存區(qū)域。為什么會(huì)內(nèi)存溢出,這是由于這塊內(nèi)存主要是被JVM存放Class和Meta信息的,Class在被Load的時(shí)候被放入PermGen space區(qū)域,它和存放Instance的Heap區(qū)域不同,sun的 GC不會(huì)在主程序運(yùn)行期對(duì)PermGen space進(jìn)行清理,所以如果你的APP會(huì)載入很多CLASS的話,就很可能出現(xiàn)PermGen space溢出。一般發(fā)生在程序的啟動(dòng)階段。
解決方法: 通過(guò)-XX:PermSize和-XX:MaxPermSize設(shè)置永久代大小即可。
3)棧溢出: java.lang.StackOverflowError : Thread Stack space
棧溢出了,JVM依然是采用棧式的虛擬機(jī),這個(gè)和C和Pascal都是一樣的。函數(shù)的調(diào)用過(guò)程都體現(xiàn)在堆棧和退棧上了。調(diào)用構(gòu)造函數(shù)的 “層”太多了,以致于把棧區(qū)溢出了。 通常來(lái)講,一般棧區(qū)遠(yuǎn)遠(yuǎn)小于堆區(qū)的,因?yàn)楹瘮?shù)調(diào)用過(guò)程往往不會(huì)多于上千層,而即便每個(gè)函數(shù)調(diào)用需要 1K的空間(這個(gè)大約相當(dāng)于在一個(gè)C函數(shù)內(nèi)聲明了256個(gè)int類(lèi)型的變量),那么棧區(qū)也不過(guò)是需要1MB的空間。通常棧的大小是1-2MB的。通俗一點(diǎn)講就是單線程的程序需要的內(nèi)存太大了。 通常遞歸也不要遞歸的層次過(guò)多,很容易溢出。
解決方法:1:修改程序。2:通過(guò) -Xss: 來(lái)設(shè)置每個(gè)線程的Stack大小即可。
4. 所以Server容器啟動(dòng)的時(shí)候我們經(jīng)常關(guān)心和設(shè)置JVM的幾個(gè)參數(shù)如下(詳細(xì)的JVM參數(shù)請(qǐng)參看附錄三):
-Xms:java Heap初始大小, 默認(rèn)是物理內(nèi)存的1/64。
-Xmx:ava Heap最大值,不可超過(guò)物理內(nèi)存。
-Xmn:young generation的heap大小,一般設(shè)置為Xmx的3、4分之一 。增大年輕代后,將會(huì)減小年老代大小,可以根據(jù)監(jiān)控合理設(shè)置。
-Xss:每個(gè)線程的Stack大小,而最佳值應(yīng)該是128K,默認(rèn)值好像是512k。
-XX:PermSize:設(shè)定內(nèi)存的永久保存區(qū)初始大小,缺省值為64M。
-XX:MaxPermSize:設(shè)定內(nèi)存的永久保存區(qū)最大大小,缺省值為64M。
-XX:SurvivorRatio:Eden區(qū)與Survivor區(qū)的大小比值,設(shè)置為8,則兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:8,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/10
-XX:+UseParallelGC:F年輕代使用并發(fā)收集,而年老代仍舊使用串行收集.
-XX:+UseParNewGC:設(shè)置年輕代為并行收集,JDK5.0以上,JVM會(huì)根據(jù)系統(tǒng)配置自行設(shè)置,所無(wú)需再設(shè)置此值。
-XX:ParallelGCThreads:并行收集器的線程數(shù),值最好配置與處理器數(shù)目相等 同樣適用于CMS。
-XX:+UseParallelOldGC:年老代垃圾收集方式為并行收集(Parallel Compacting)。
-XX:MaxGCPauseMillis:每次年輕代垃圾回收的最長(zhǎng)時(shí)間(最大暫停時(shí)間),如果無(wú)法滿足此時(shí)間,JVM會(huì)自動(dòng)調(diào)整年輕代大小,以滿足此值。
-XX:+ScavengeBeforeFullGC:Full GC前調(diào)用YGC,默認(rèn)是true。
實(shí)例如:JAVA_OPTS=”-Xms4g -Xmx4g -Xmn1024m -XX:PermSize=320M -XX:MaxPermSize=320m -XX:SurvivorRatio=6″
posted on 2016-07-26 23:05
胡小軍 閱讀(343)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
JVM