Tomcat常見的內存溢出,以及解決方法


  一.常見的三種內存溢出錯誤

    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都會使用最新加入的優化技術(如果有的話)

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM