一.常見的三種內存溢出錯誤:
1.java.lang.OutOfMemoryError:java heap space ====JVM Heap(堆)溢出
JVM再啟動的時候回自動設置JVM Heap的值,其初始化空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)不可超過物理內存。
可以利用JVM提供的-Xmn -Xms -Xmx等選項進行設置。
Heap的大小是Young Genration和Tenured Generaion之和。
在JVM中如果98%的時間是用於GC,且可用的Heap size不足2%的時候將拋出異常信息。
解決方法:
手動設置JVM Heap(堆)的大小。
2.java.long.StackOverflowError:PermGen space ==== PermGen space溢出。
PermGen space的全程是Permanent Generation space,是指內存的永久保存區域。
為什么會內存溢出,這是由於這塊內存主要是被JVM存放的Class和Meata信息的,
Class被Load的時候被放入PermGen space區域,它和存放Instace的Heap區域不同,
sun的GC不會在主程序運行期對PermGen space進行清理,所以如果你的APP會在如很多CLASS的話,
就可能出現PermGen space溢出。
解決方法:手動設置MaxPermSize大小
3.java.long.StackOverflowError =======棧溢出
棧溢出了,JVM依然是采用棧時的虛擬機,這個和C和Pascal都是一樣的。函數的調用過程都體現在堆棧和退棧上了。
調用構造函數的 "層" 太多了,以至於把棧區溢出了。
通常來講,一般棧區遠遠小於堆區的,因為函數調用過程往往不會多余上千層,而即使每個函數調用需要1K的空間
(這個大約相當於C函數內聲明了256個int類型的變量,那么棧區也不過需要1MB的空間。通常棧的大小 1-2MB的。
通常遞歸也不要遞歸層次過多,很容易溢出。
解決方法:修改程序。
二:解決方法
在生產環境中tomcat內存設置不好很容易出現JVM內存溢出。
1、linux下的tomcat:
修改TOMCAT_HOME/bin/catalina.sh
在echo “Using CATALINA_BASE:$CATALINA_BASE"上面加上如下行:
JAVA_OPTS="-server -Xms256m -Xmx 512m -XXPermSize=64M -XX:MaxPermSize=128m"
1.如果tomcat5注冊沖windows服務,以services方式啟動的,則需要修改注冊表中的鍵值。
修改注冊表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Tomcat Service Manager\Tomcat5\
Parameters\Java.右側的Options原值為:
-Dcatalina.home="C:\ApacheGroup\Tomcat 5.0"
-Djava.endorsed.dirs="C:\ApacheGroup\Tomcat 5.0\common\endorsed"
-Xrs
加入-Xms256m -Xmx512m
重啟tomncat,設置生效
3.如果tomcat6 注冊成立windows服務,或者windows2003下用tomcat的安裝版
在/bin/tomcat6w.exe里修改就可以了。
4.如果在myeclipse中啟動tomcat,上述修改不起作用,可如下設置:
MyEclipse→preferences→servers→tomcat→tomcat.x.x:→JDK面板中的
Optional Java VM arguments中添加:-Xms256m -Xmx512m -xx:PermSize:64M
-XX:MaxPermSize=128m
三、JVM參數說明:
-server:一定要作為第一個參數,在多個CUP時性能佳
-Xms:java Heap初始化大小。默認物理內存的1/64
-Xmx:java Heap最大值。建議平均物理內存的一般。不可超過物理內存。
-XX:PermSize:設定內存的永久保存區初始化大小,缺省為64M
-XX:MaxPermSize:設定內存的永久保存區最大大小,缺省委64M、
-XX:SurvivorRatio=2:生還者池的大小,默認是2,如果垃圾回收變成了瓶頸,您可以嘗試定值生成池設置
-XX:NewSize:新生成的池初始化大小,缺省為2M。
-XX:MaxNewSize:新生成的池最大大小。缺省為32M。
如果JVM的堆大小大於1GB,則應該使用值-XX:newSize=640M-XXSurvivorRatio=16,或者將總堆大小的50%到60%分配給新生的池。調大新對象區,減少Full GC次數
-XX:AggressiveHep會是Xms沒意義。
這參數讓JVM忽略Xmx參數,瘋狂地吃完一個G物理內存,再吃盡1個G的swap。
-Xss:每個線程的Stack大小,-Xss 15120這使得JBoss沒增加一個線程就會消耗15M內存,而最佳值應該是128k,默認512k
-verbose:gc 實現垃圾回收信息
-Xloggc:gc.log指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般設置為Xmx的3,4之一
-XX:+UseParNewGC:所短minor收集的時間
-XX:+UserConcMarkSweepGC:所短major收集的時間 次選項在Heap Size比較大而且Major收集較長的情況下使用更合適。
-XX:userParNewGC 可用來設置多個並行收集(多CPU)
-XX:ParallelGCThreads可用來增加並行度(多CPU)
-XX:UseParallelGC設置后可以使用並行清理收集器(多CPU)
-XX:+UseBiasedLocking非競爭性的同步選項,鎖機制的性能改善。
-XX:+DisableExplicitGC 禁止System.gc(),免得程序員誤調用gc方法影響性能。
-XX:MaxTenuringThreshold 為放置所有的復制全部發生以及希望對象從eden擴展到舊域,可以把MaxTenuring Threshold設置成0。設置完成后,實際上就不再使用救助空間了,因此應把SurvivorRatio設成最大值以最大化Eden空間,設置如下:
-XX:+UseParNewGC 對年輕代采用多線程並行回收,這樣收得快。
-XX:+CMSParallelRemarkEnabled 在使用UseParNewGC 的情況下, 盡量減少 mark 的時間
-XX:LargePageSizeInBytes 指定 Java heap的分頁頁面大小
-XX:MaxTenuringThreshold 設置垃圾最大年齡。如果設置為0的話,則年輕代對象不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設置為一個較大值,則年輕代對象會在Survivor區進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概率。
這個值的設置是根據本地的jprofiler監控后得到的一個理想的值,不能一概而論原搬照抄。
-XX:+UseBiasedLocking 啟用一個優化了的線程鎖,我們知道在我們的appserver,每個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appserver內對線程處理自動進行最優調配。
-XX:+AggressiveOpts 作用如其名(aggressive),啟用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術(如果有的話)
