JRockit檢測Tomcat內存溢出JAVA內存泄漏問題

http://blog.csdn.net/liyanhui1001/article/details/8240473html

 

公司的一個Java應用系統上線以來,基本每1天OutOfMemoryError: PermGen space一次。JAVA堆上限1個G,出現了好屢次,想到JRockit能夠分析內存泄漏的問題:
1. JRockit簡介
Jrockit是Bea開發的符合JAVA虛擬機規範的虛擬機+虛擬機監控軟件。
虛擬機:Jrockit Real Time
監控軟件:Jrockit Mission Control
Jrockit Real Time與SUN的JDK是徹底兼容的,也就是說之前在SUN的虛擬機上跑的程序,在Jrockit Real Time上不會出現任何問題。
之前這套軟件只提供1個小時的免費監控時間。就是說虛擬機啓動1個小時內監控軟件能夠連上,過了一個小時就連不上了。這對一天才泄漏20M的應用程序來講,沒有什麼意義。如今已經徹底免費了。這是開發者的福音。
最重要的,Jrockit是目前做者嘗試過的,惟一一套能夠在生產環境中進行內存監控的軟件,其餘軟件都會嚴重下降虛擬機的效率應用基本沒法使用。由於內存泄漏有時就算在壓力測試中也很難發現。大部分都是在生產環境中產生的。若是沒有一個基本不影響運行效率的軟件,想解決只能靠運氣。之前我解決過一次JAVA內存泄漏的問題,將程序從WEBLOGIC遷移到TOMCAT上解決了決徹底屬於運氣。如今有了這個工具,解決起來就很是方便了。

2. 下載JRockit3.1.0,並安裝
下載地址:http://www.oracle.com/technology/software/products/jrockit/index.html
要同時下載Jrockit Mission Control 3.1.0(監控軟件)和Jrockit Real Time 3.1.0(虛擬機) 

3. 服務器端配置
1. 在服務器段安裝Jrockit Real Time 3.1.0,
2. 設置應用程序,使用此Jrockit啓動應用程序。
Tomcat 6的設置方法是:
在catalina.sh頂部加入
JAVA_OPTS=" -verbosegc -Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=本機IP "和
JRE_HOME="Jrockit虛擬機路徑"
將JRE_HOME改成JAVA_HOME也行。
3. 下載http://download2.bea.com/pub/license/All%20Products/BEA_WebLogic.zip,解壓後將其中的LIC-WLRT20.txt文件更名爲license.bea上傳到%JROCKIT_HOME%/jre/下。
4. 監控端設置
首先安裝Jrockit Mission Control 3.1.0,而後運行之。
在JVM瀏覽器視圖中,對鏈接器文件夾右鍵,選擇新建鏈接。彈出下圖:
java




在「主機」處輸入IP,服務器開放的端口已是7091,因此沒必要修改。其餘的不用動。點擊「測試鏈接」狀態若是是肯定則表明已經鏈接。點擊Finish保存新建的鏈接。在「鏈接器」文件夾新建了一個鏈接。
5. 開始監控內存
在新建的鏈接器上點擊右鍵,選擇「啓動Memleak」,如圖:


彈出內存泄露檢測器,如圖:



最早看見的是「趨勢」選項卡,裏邊標註了佔用JAVA堆大於0.1%的類和數組。
「類型」選項卡,顯示了類型與類型之間的引用狀況。
「實例」選項卡,顯示了實例之間的引用狀況。
「分配堆棧跟蹤」選項卡,顯示了指定類型在虛擬機運行過程當中被使用的狀況。
6. 實戰
公司的一個JAVA應用系統上線以來,基本每1天OutOfMemory一次。JAVA堆上限1個G。
6.1 10點45份內存使用狀況抓屏(趨勢選項卡)
注:抓屏前都進行了徹底的垃圾回收。



6.2 13點17份內存使用狀況抓屏




6.3 結論
佔用內存最高的類爲:
edu.emory.mathcs.java.util.concurrent.ConcurrentHashMap$Segment
此類從10點多的95M漲到13點的129M。沒有釋放內存。此類引發內存泄露。
edu.emory.mathcs屬於backport-util-concurrent開源項目。用於線程併發編程。屬於java.util.concurrent包的另外一個實現。
7. 堆棧分配跟蹤
知道是那個類出了問題,而後就須要知道系統中都那些類使用了這個問題。在edu.emory.mathcs.java.util.concurrent.ConcurrentHashMap$Segment上右鍵,選擇「顯示分配跟蹤」,進入「分配堆棧跟蹤」選項卡,
跟蹤一段時間如圖:



此時就會發現,使用backport-util-concurrent的是AXIS2,使用AXIS2的是咱們項目裏的文件,而且裏邊已經標註了堆棧(包名.類名.方法名(文件名:行數) ),這樣就知道那裏出現問題,對症下藥就可以解決了。去修改代碼吧。HOHO~

來源:Heck's Blog
地址:http://www.hecks.tk/JRockit-testing-OutOfMemoryError-PermGen-space/編程

相關文章
相關標籤/搜索