隨筆-204  評(píng)論-90  文章-8  trackbacks-0


          摘自:http://dikar.javaeye.com/blog/643436

                  如題,我這里簡(jiǎn)單說(shuō)下我現(xiàn)在離線分析java內(nèi)存的方式,所謂離線,就是需要dump出正在運(yùn)行的java系統(tǒng)中的一些運(yùn)行時(shí)堆棧數(shù)據(jù),然后拿到線下來(lái)分析,分析可以包括內(nèi)存,線程,GC等等,同時(shí)不會(huì)對(duì)正在運(yùn)行的生產(chǎn)環(huán)境的機(jī)器造成很大的影響,對(duì)應(yīng)著離線分析,當(dāng)然是在線分析了,這個(gè)我在后面會(huì)嘗試下,因?yàn)殡x線分析有些場(chǎng)景還是模擬不出來(lái),需要借助LR來(lái)模擬壓力,查看在線的java程序運(yùn)行情況了。

           

                      首先一個(gè)簡(jiǎn)單的問(wèn)題,如何dump出java運(yùn)行時(shí)堆棧,這個(gè)SUN就提供了很好的工具,位于JAVA_HOME/bin目錄下的jmap(java memory map之意),如果需要dump出當(dāng)前運(yùn)行的java進(jìn)程的堆棧數(shù)據(jù),則首先需要獲得該java進(jìn)程的進(jìn)程ID,在linux下可以使用

          Java代碼 復(fù)制代碼
          1. ps -aux   
          2.   
          3. ps -ef | grep java  

           

          或者使用jdk自帶的一個(gè)工具jps,例如

           

          Java代碼 復(fù)制代碼
          1. /JAVA_HOME/bin/jps  

           

          找到了當(dāng)前運(yùn)行的java進(jìn)程的id后,就可以對(duì)正在運(yùn)行的java進(jìn)程使用jmap工具進(jìn)行dump了,例如使用以下命令:

           

          Java代碼 復(fù)制代碼
          1. JAVA_HOME/bin/jmap  -dump:format=b,file=heap.bin <pid>   

           

          其中file = heap.bin的意思是dump出的文件名叫heap.bin, 當(dāng)然你可以選擇你喜歡的名字,我這里選擇叫*.bin是為了后面使用方便,<pid>表示你需要dump的java進(jìn)程的id。


          這里需要注意的是,記住dump的進(jìn)程是java進(jìn)程,不會(huì)是jboss的進(jìn)程,weblogic的進(jìn)程等。dump過(guò)程中機(jī)器load可能會(huì)升高,但是在我這里測(cè)試發(fā)現(xiàn)load升的不是特別快,同時(shí)dump時(shí)需要的磁盤空間也比較大,例如我這里測(cè)試的幾個(gè)系統(tǒng),分別是500M 800M 1500M  3000M,所以確保你運(yùn)行jmap命令時(shí)所在的目錄中的磁盤空間足夠,當(dāng)然現(xiàn)在的系統(tǒng)磁盤空間都比較大。

           

          以上是在java進(jìn)程還存活的時(shí)候進(jìn)行的dump,有的時(shí)候我們的java進(jìn)程crash后,會(huì)生成一個(gè)core.pid文件,這個(gè)core.pid文件還不能直接被我們的java 內(nèi)存分析工具使用,需要將其轉(zhuǎn)換為java 內(nèi)存分析工具可以讀的文件(例如使用jmap工具dump出的heap.bin文件就是很多java 內(nèi)存分析工具可以讀的文件格式)。將core.pid文件轉(zhuǎn)換為jmap工具dump出的文件格式還可以繼續(xù)使用jmap工具,這個(gè)的說(shuō)明可以見(jiàn)我前幾篇中的一個(gè)轉(zhuǎn)載(Create Java heapdumps with the help of core dumps ),這里我在補(bǔ)充點(diǎn)

           

           

          Java代碼 復(fù)制代碼
          1. jmap -heap:format=b [java binary] [core dump file]   
          2.   
          3.   
          4. jmap -dump:format=b,file=dump.hprof [java binary] [core dump file]   
          5.   
          6.   
          7. 64位下可以指定使用64位模式   
          8.   
          9. jmap -d64  -dump:format=b,file=dump.hprof [java binary] [core dump file]  
           

          需要說(shuō)明一下,使用jmap轉(zhuǎn)換core.pid文件時(shí),當(dāng)文件格式比較大時(shí),可能大于2G的時(shí)候就不能執(zhí)行成功(我轉(zhuǎn)換3G文件大小的時(shí)候沒(méi)有成功)而報(bào)出

           

          Error attaching to core file: Can't attach to the core file

           

          查過(guò)sun的bug庫(kù)中,這個(gè)bug還沒(méi)有被修復(fù),我想還是由于32位下用戶進(jìn)程尋址大小限制在2G的范圍內(nèi)引起的,在64位系統(tǒng)和64位jdk版本中,轉(zhuǎn)換3G文件應(yīng)該沒(méi)有什么大的問(wèn)題(有機(jī)會(huì)有環(huán)境得需要測(cè)試下)。如果有興趣分析jmap轉(zhuǎn)換不成功的同學(xué),可以使用如下命令來(lái)分析跟蹤命令的執(zhí)行軌跡,例如使用

           

          Java代碼 復(fù)制代碼
          1. strace  jmap -heap:format=b [java binary] [core dum  

           對(duì)于strace的命令的說(shuō)明,同樣可以參考我前幾篇文章中的一個(gè) strace命令用法


          同時(shí)對(duì)于core.pid文件的調(diào)試我也補(bǔ)充一下, 其中>>表示命令提示符

           

          Java代碼 復(fù)制代碼
          1. >>gdb JAVA_HOME/bin/java  core.pid   
          2.   
          3. >>bt  
           

          bt后就可以看到生成core.pid文件時(shí),系統(tǒng)正在執(zhí)行的一個(gè)操作,例如是哪個(gè)so文件正在執(zhí)行等。

           

          好了說(shuō)了這么多,上面都是怎么生成java 運(yùn)行期DUMP文件的,接下來(lái)我們就進(jìn)入分析階段,為了分析這個(gè)dump出的文件,需要將這個(gè)文件弄到你的分析程序所在的機(jī)器上,例如可以是windows上,linux上,這個(gè)和你使用的分析工具以及使用的操作系統(tǒng)有關(guān)。不管使用什么系統(tǒng),總是需要把生產(chǎn)環(huán)境下打出的dump文件搞到你的分析機(jī)器上,由于dump出的文件經(jīng)常會(huì)比較大,例如達(dá)到2G,這么大的文件不是很好的從生產(chǎn)環(huán)境拉下來(lái),因此使用FTP的方式把文件拖到分析機(jī)器上,同時(shí)由于單個(gè)文件很大,因此為了快速的將文件下載到分析機(jī)器,我們可以使用分而治之的思想,先將文件切割為小文件下載,然后在合并為一個(gè)大文件即可,還好linux提供了很方便的工具,例如使用如下命令

           

          Java代碼 復(fù)制代碼
          1. $ split -b 300m heap.bin   
          2.   
          3.  $ cat x* > heap.bin  


          在上面的 split 命令行中的 “300m” 表示分割后的每個(gè)文件為 300MB,“heap.bin” 為待分割的dump文件,分割后的文件自動(dòng)命名為 xaa,xab,xac等

          cat 命令可將這些分割后的文件合并為一個(gè)文件,例如將所有x開(kāi)頭的文件合并為heap.bin

           

          如果我們是利用一個(gè)中間層的FTP服務(wù)器來(lái)保存數(shù)據(jù)的,那么我們還需要連接這個(gè)FTP服務(wù)器把合并后的文件拉下來(lái),在windows下我推薦使用一個(gè)工具,速度很快而且簡(jiǎn)單,

          winscp   http://winscp.net/eng/docs/lang:chs


          好了分析的文件終于經(jīng)過(guò)一翻周折到了你的分析機(jī)器上,現(xiàn)在我們就可以使用分析工具來(lái)分析這個(gè)dump出的程序了,這里我主要是分析內(nèi)存的問(wèn)題,所以我說(shuō)下我選擇的內(nèi)存分析工具,我這里使用的是開(kāi)源的由SAP 和IBM 支持的一個(gè)內(nèi)存分析工具

          Memory Analyzer (MAT)

          http://www.eclipse.org/mat/

           

          我建議下載 Stand-alone Eclipse RCP 版本,不要裝成eclipse的插件,因?yàn)檫@個(gè)分析起來(lái)還是很耗內(nèi)存。

           

          下載好了,解壓開(kāi)來(lái)就可以直接使用了(基于eclipse的),打開(kāi)以后,在菜單欄中選擇打開(kāi)文件,選擇你剛剛的dump文件,然后一路的next就可以了,最后你會(huì)看到一個(gè)報(bào)告,這個(gè)報(bào)告里會(huì)告訴你可能的內(nèi)存泄露的點(diǎn),以及內(nèi)存中對(duì)象的一個(gè)分布,關(guān)于mat的使用請(qǐng)參考官方說(shuō)明,當(dāng)然你也可以自己徜徉在學(xué)習(xí)的海洋中

           

          對(duì)于dump文件的分析還可以使用jdk中提供的一個(gè)jhat工具來(lái)查看,不過(guò)這個(gè)很耗內(nèi)存,而且默認(rèn)的內(nèi)存大小不夠,還需要增加參數(shù)設(shè)置內(nèi)存大小才能分析出,不過(guò)我看了下分析出的結(jié)果不是很滿意,而且這個(gè)用起來(lái)很慢。還是推薦使用mat

          posted on 2010-05-07 10:31 一凡 閱讀(2905) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA 基礎(chǔ)
          主站蜘蛛池模板: 阳春市| 台前县| 醴陵市| 攀枝花市| 平江县| 嘉善县| 凭祥市| 馆陶县| 昌江| 固原市| 镶黄旗| 和林格尔县| 含山县| 道孚县| 宁化县| 长兴县| 新营市| 筠连县| 长垣县| 西乌珠穆沁旗| 阿克陶县| 大渡口区| 阜新市| 阳山县| 日土县| 周宁县| 塔城市| 南陵县| 天峻县| 延庆县| 蒙阴县| 灵丘县| 盐山县| 弋阳县| 岑溪市| 菏泽市| 云梦县| 会昌县| 合山市| 开封县| 青阳县|