關於tomcat內存查看

Tomcat 優化 java.lang.OutOfMemoryError: Java heap space 的解決方法
   java

java.lang.OutOfMemoryError: Java heap space 的解決方法mysql

關鍵字: tomcat outofmemoryerror permgen space java heap spacelinux

最近在熟悉一個開發了有幾年的項目,須要把數據庫從mysql移植到oracle,首先把jdbc 的鏈接指向mysql,打包放到tomcat裏面,能夠跑起來,沒有問題,但是當把jdbc鏈接指向oracle的時候,tomcat就連續拋 java.lang.OutOfMemoryError的錯誤,上網google了一下,瞭解了一下tomcat的運行機制,也解決了問題,share出 來,以備查。

一、首先是:java.lang.OutOfMemoryError: Java heap space

解釋:

Heap size 設置

JVM 堆的設置是指java程序運行過程當中JVM能夠調配使用的內存空間的設置.JVM在啓動的時候會自動設置Heap size的值,其初始空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)是物理內存的1/4。能夠利用JVM提供的-Xmn -Xms -Xmx等選項可進行設置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
提示:在JVM中若是98%的時間是用於GC且可用的Heap size 不足2%的時候將拋出此異常信息。
提示:Heap Size 最大不要超過可用物理內存的80%,通常的要將-Xms和-Xmx選項設置爲相同,而-Xmn爲1/4的-Xmx值。

解決方法:

手動設置Heap size
修改TOMCAT_HOME/bin/catalina.bat,在「echo "Using CATALINA_BASE: $CATALINA_BASE"」上面加入如下行:
set JAVA_OPTS=%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize=256m

或修改catalina.sh
在「echo "Using CATALINA_BASE: $CATALINA_BASE"」上面加入如下行:
JAVA_OPTS="$JAVA_OPTS -server -Xms800m -Xmx800m -XX:MaxNewSize=256m"

二、其次是:java.lang.OutOfMemoryError: PermGen space

緣由:

PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域,這塊內存主要是被JVM存放Class和Meta信息的,Class在被Loader時就會被放到PermGen space中,它和存放類實例(Instance)的Heap區域不一樣,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,因此若是你的應用中有很CLASS的話,就極可能出現PermGen space錯誤,這種錯誤常見在web服務器對JSP進行pre compile的時候。若是你的WEB APP下都用了大量的第三方jar, 其大小超過了jvm默認的大小(4M)那麼就會產生此錯誤信息了。

解決方法:

1. 手動設置MaxPermSize大小
修改TOMCAT_HOME/bin/catalina.bat(Linux下爲catalina.sh),在「echo "Using CATALINA_BASE: $CATALINA_BASE"」上面加入如下行:
set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m

catalina.sh下爲:
JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m"


另外看到了另一個帖子,以爲挺好,摘抄以下:
分析java.lang.OutOfMemoryError: PermGen space

發 現不少人把問題歸因於: spring,hibernate,tomcat,由於他們動態產生類,致使JVM中的permanent heap溢出 。而後解決方法衆說紛紜,有人說升級 tomcat版本到最新甚至乾脆不用tomcat。還有人懷疑spring的問題,在spring論壇上討論很激烈,由於spring在AOP時使用 CBLIB會動態產生不少類。

但問題是爲何這些王牌的開源會出現同一個問題呢,那麼是否是更基礎的緣由呢?tomcat在Q&A很隱晦的回答了這一點,咱們知道這個問題,但這個問題是由一個更基礎的問題產生。

於 是有人對更基礎的JVM作了檢查,發現了問題的關鍵。原來SUN 的JVM把內存分了不一樣的區,其中一個就是permenter區用來存放用得很是多的類和類描述。原本SUN設計的時候認爲這個區域在JVM啓動的時候就 固定了,但他沒有想到如今動態會用得這麼普遍。並且這個區域有特殊的垃圾收回機制,如今的問題是動態加載類到這個區域後,gc根本沒辦法回收!


對於以上兩個問題,個人處理是:

在catalina.bat的第一行增長:
set JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

在catalina.sh的第一行增長:
JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
web




~~~~~~~~~~~~~~~~~~~~~~~~spring


命令格式

jstat命令命令格式:

jstat [Options] vmid [interval] [count]
sql

參數說明:

Options,選項,咱們通常使用 -gcutil 查看gc狀況
vmid,VM的進程號,即當前運行的java進程號
interval,間隔時間,單位爲秒或者毫秒
count,打印次數,若是缺省則打印無數次
數據庫

示例說明

示例

一般運行命令以下:tomcat

jstat -gc 12538 5000
服務器

即會每5秒一次顯示進程號爲12538的java進成的GC狀況,oracle

顯示內容以下圖:



結果說明

顯示內容說明以下(部分結果是經過其餘其餘參數顯示的,暫不說明):

         S0C:年輕代中第一個survivor(倖存區)的容量 (字節) 
         S1C:年輕代中第二個survivor(倖存區)的容量 (字節) 
         S0U:年輕代中第一個survivor(倖存區)目前已使用空間 (字節) 
         S1U:年輕代中第二個survivor(倖存區)目前已使用空間 (字節) 
         EC:年輕代中Eden(伊甸園)的容量 (字節) 
         EU:年輕代中Eden(伊甸園)目前已使用空間 (字節) 
         OC:Old代的容量 (字節) 
         OU:Old代目前已使用空間 (字節) 
         PC:Perm(持久代)的容量 (字節) 
         PU:Perm(持久代)目前已使用空間 (字節) 
         YGC:從應用程序啓動到採樣時年輕代中gc次數 
         YGCT:從應用程序啓動到採樣時年輕代中gc所用時間(s) 
         FGC:從應用程序啓動到採樣時old代(全gc)gc次數 
         FGCT:從應用程序啓動到採樣時old代(全gc)gc所用時間(s) 
         GCT:從應用程序啓動到採樣時gc用的總時間(s) 
         NGCMN:年輕代(young)中初始化(最小)的大小 (字節) 
         NGCMX:年輕代(young)的最大容量 (字節) 
         NGC:年輕代(young)中當前的容量 (字節) 
         OGCMN:old代中初始化(最小)的大小 (字節) 
         OGCMX:old代的最大容量 (字節) 
         OGC:old代當前新生成的容量 (字節) 
         PGCMN:perm代中初始化(最小)的大小 (字節) 
         PGCMX:perm代的最大容量 (字節)   
         PGC:perm代當前新生成的容量 (字節) 
         S0:年輕代中第一個survivor(倖存區)已使用的佔當前容量百分比 
         S1:年輕代中第二個survivor(倖存區)已使用的佔當前容量百分比 
         E:年輕代中Eden(伊甸園)已使用的佔當前容量百分比 
         O:old代已使用的佔當前容量百分比 
         P:perm代已使用的佔當前容量百分比 
         S0CMX:年輕代中第一個survivor(倖存區)的最大容量 (字節) 
         S1CMX :年輕代中第二個survivor(倖存區)的最大容量 (字節) 
         ECMX:年輕代中Eden(伊甸園)的最大容量 (字節) 
         DSS:當前須要survivor(倖存區)的容量 (字節)(Eden區已滿) 
         TT: 持有次數限制 
         MTT : 最大持有次數限制

~~~~~~~~~~~~~~~~~~~


jmap (linux下特有,也是很經常使用的一個命令)

觀察運行中的jvm物理內存的佔用狀況。

參數以下:

-heap :打印jvm heap的狀況
-histo: 打印jvm heap的直方圖。其輸出信息包括類名,對象數量,對象佔用大小。
-histo:live : 同上,可是隻答應存活對象的狀況
-permstat: 打印permanent generation heap狀況

命令使用:

jmap -heap 3409

能夠觀察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的內存使用狀況

輸出內容:

jmap -histo 3409 | jmap -histo:live 3409

能夠觀察heap中全部對象的狀況(heap中全部生存的對象的狀況)。包括對象數量和所佔空間大小。

輸出內容:

寫個腳本,能夠很快把佔用heap最大的對象找出來,對付內存泄漏特別有效。

 

若是結果不少,能夠用如下命令輸出到文本文件。jmap -histo 3409 | jmap -histo:live 3409 > a.txt

相關文章
相關標籤/搜索