1. JRockit簡(jiǎn)介
Jrockit是Bea開(kāi)發(fā)的符合JAVA虛擬機(jī)規(guī)范的虛擬機(jī)+虛擬機(jī)監(jiān)控軟件。
虛擬機(jī):Jrockit Real Time
監(jiān)控軟件:Jrockit Mission Control
Jrockit Real Time與SUN的JDK是完全兼容的,也就是說(shuō)以前在SUN的虛擬機(jī)上跑的程序,在Jrockit Real Time上不會(huì)出現(xiàn)任何問(wèn)題。
以前這套軟件只提供1個(gè)小時(shí)的免費(fèi)監(jiān)控時(shí)間。就是說(shuō)虛擬機(jī)啟動(dòng)1個(gè)小時(shí)內(nèi)監(jiān)控軟件可以連上,過(guò)了一個(gè)小時(shí)就連不上了。這對(duì)一天才泄漏20M的應(yīng)用程序來(lái)說(shuō),沒(méi)有什么意義?,F(xiàn)在已經(jīng)完全免費(fèi)了。這是開(kāi)發(fā)者的福音。
最重要的,Jrockit是目前作者嘗試過(guò)的,唯一一套可以在生產(chǎn)環(huán)境中進(jìn)行內(nèi)存監(jiān)控的軟件,其他軟件都會(huì)嚴(yán)重降低虛擬機(jī)的效率應(yīng)用基本無(wú)法使用。因?yàn)閮?nèi)存泄漏有時(shí)就算在壓力測(cè)試中也很難發(fā)現(xiàn)。大部分都是在生產(chǎn)環(huán)境中產(chǎn)生的。如果沒(méi)有一個(gè)基本不影響運(yùn)行效率的軟件,想解決只能靠運(yùn)氣。以前我解決過(guò)一次JAVA內(nèi)存泄漏的問(wèn)題,將程序從WEBLOGIC遷移到TOMCAT上解決了決完全屬于運(yùn)氣?,F(xiàn)在有了這個(gè)工具,解決起來(lái)就非常方便了。
2. 下載JRockit3.1.0,并安裝
下載地址:http://www.oracle.com/technology/software/products/jrockit/index.html
要同時(shí)下載Jrockit Mission Control 3.1.0(監(jiān)控軟件)和Jrockit Real Time 3.1.0(虛擬機(jī))
3. 服務(wù)器端配置
1. 在服務(wù)器段安裝Jrockit Real Time 3.1.0,
2. 設(shè)置應(yīng)用程序,使用此Jrockit啟動(dòng)應(yīng)用程序。
Tomcat 6的設(shè)置方法是:
在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=本機(jī)IP "和
JRE_HOME="Jrockit虛擬機(jī)路徑"
將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. 監(jiān)控端設(shè)置
首先安裝Jrockit Mission Control 3.1.0,然后運(yùn)行之。
在JVM瀏覽器視圖中,對(duì)連接器文件夾右鍵,選擇新建連接。彈出下圖:
在“主機(jī)”處輸入IP,服務(wù)器開(kāi)放的端口已經(jīng)是7091,所以不必修改。其他的不用動(dòng)。點(diǎn)擊“測(cè)試連接”狀態(tài)如果是確定則代表已經(jīng)連接。點(diǎn)擊Finish保存新建的連接。在“連接器”文件夾新建了一個(gè)連接。
5. 開(kāi)始監(jiān)控內(nèi)存
在新建的連接器上點(diǎn)擊右鍵,選擇“啟動(dòng)Memleak”,如圖:
IMG
彈出內(nèi)存泄露檢測(cè)器,如圖:
IMG
最先看見(jiàn)的是“趨勢(shì)”選項(xiàng)卡,里邊標(biāo)注了占用JAVA堆大于0.1%的類(lèi)和數(shù)組。
“類(lèi)型”選項(xiàng)卡,顯示了類(lèi)型與類(lèi)型之間的引用情況。
“實(shí)例”選項(xiàng)卡,顯示了實(shí)例之間的引用情況。
“分配堆棧跟蹤”選項(xiàng)卡,顯示了指定類(lèi)型在虛擬機(jī)運(yùn)行過(guò)程中被使用的情況。
6. 實(shí)戰(zhàn)
公司的一個(gè)JAVA應(yīng)用系統(tǒng)上線以來(lái),基本每1天OutOfMemory一次。JAVA堆上限1個(gè)G。
6.1 10點(diǎn)45分內(nèi)存使用情況抓屏(趨勢(shì)選項(xiàng)卡)
注:抓屏前都進(jìn)行了完全的垃圾回收。
IMG
6.2 13點(diǎn)17分內(nèi)存使用情況抓屏
IMG
6.3 結(jié)論
占用內(nèi)存最高的類(lèi)為:
edu.emory.mathcs.java.util.concurrent.ConcurrentHashMap$Segment
此類(lèi)從10點(diǎn)多的95M漲到13點(diǎn)的129M。沒(méi)有釋放內(nèi)存。此類(lèi)引起內(nèi)存泄露。
edu.emory.mathcs屬于backport-util-concurrent開(kāi)源項(xiàng)目。用于線程并發(fā)編程。屬于java.util.concurrent包的另一個(gè)實(shí)現(xiàn)。
7. 堆棧分配跟蹤
知道是那個(gè)類(lèi)出了問(wèn)題,然后就需要知道系統(tǒng)中都那些類(lèi)使用了這個(gè)問(wèn)題。在edu.emory.mathcs.java.util.concurrent.ConcurrentHashMap$Segment上右鍵,選擇“顯示分配跟蹤”,進(jìn)入“分配堆棧跟蹤”選項(xiàng)卡,
跟蹤一段時(shí)間如圖:
IMG
此時(shí)就會(huì)發(fā)現(xiàn),使用backport-util-concurrent的是AXIS2,使用AXIS2的是我們項(xiàng)目里的文件,并且里邊已經(jīng)標(biāo)注了堆棧(包名.類(lèi)名.方法名(文件名:行數(shù)) ),這樣就知道那里出現(xiàn)問(wèn)題,對(duì)癥下藥就能夠解決了。去修改代碼吧。HOHO~