天天看點

離線分析java記憶體

如題,我這裡簡單說下我現在離線分析java記憶體的方式,所謂離線,就是需要

dump出正在運作的java系統中的一些運作時堆棧資料,然後拿到線下來分析,分析可以包括記憶體,線程,GC等等,同時不會對正在運作的生産環境的機器

造成很大的影響,對應着離線分析,當然是線上分析了,這個我在後面會嘗試下,因為離線分析有些場景還是模拟不出來,需要借助LR來模拟壓力,檢視線上的

java程式運作情況了。

            首先一個簡單的問題,如何dump出java運作時堆棧,這個SUN就提供了很好的工具,位于JAVA_HOME/bin目錄下的jmap(java memory map之意),如果需要dump出目前運作的java程序的堆棧資料,則首先需要獲得該java程序的程序ID,在linux下可以使用

Java代碼

ps -aux   

ps -ef | grep java  

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

/JAVA_HOME/bin/jps  

找到了目前運作的java程序的id後,就可以對正在運作的java程序使用jmap工具進行dump了,例如使用以下指令:

JAVA_HOME/bin/jmap  -dump:format=b,file=heap.bin <pid>   

其中file = heap.bin的意思是dump出的檔案名叫heap.bin, 當然你可以選擇你喜歡的名字,我這裡選擇叫*.bin是為了後面使用友善,<pid>表示你需要dump的java程序的id。

這裡需要注意的是,記住dump的程序是java程序,不會是jboss的進

程,weblogic的程序等。dump過程中機器load可能會升高,但是在我這裡測試發現load升的不是特别快,同時dump時需要的磁盤空間也比

較大,例如我這裡測試的幾個系統,分别是500M 800M 1500M 

3000M,是以確定你運作jmap指令時所在的目錄中的磁盤空間足夠,當然現在的系統磁盤空間都比較大。

以上是在java程序還存活的時候進行的dump,有的時候我們的java程序

crash後,會生成一個core.pid檔案,這個core.pid檔案還不能直接被我們的java 記憶體分析工具使用,需要将其轉換為java

記憶體分析工具可以讀的檔案(例如使用jmap工具dump出的heap.bin檔案就是很多java

記憶體分析工具可以讀的檔案格式)。将core.pid檔案轉換為jmap工具dump出的檔案格式還可以繼續使用jmap工具,這個的說明可以見我前幾篇

中的一個轉載(Create Java heapdumps with the help of core dumps ),這裡我在補充點

jmap -heap:format=b [java binary] [core dump file]   

jmap -dump:format=b,file=dump.hprof [java binary] [core dump file]   

64位下可以指定使用64位模式   

jmap -d64  -dump:format=b,file=dump.hprof [java binary] [core dump file]  

需要說明一下,使用jmap轉換core.pid檔案時,當檔案格式比較大時,可能大于2G的時候就不能執行成功(我轉換3G檔案大小的時候沒有成功)而報出

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

查過sun的bug庫中,這個bug還沒有被修複,我想還是由于32位下使用者程序

尋址大小限制在2G的範圍内引起的,在64位系統和64位jdk版本中,轉換3G檔案應該沒有什麼大的問題(有機會有環境得需要測試下)。如果有興趣分析

jmap轉換不成功的同學,可以使用如下指令來分析跟蹤指令的執行軌迹,例如使用

strace  jmap -heap:format=b [java binary] [core dum  

 對于strace的指令的說明,同樣可以參考我前幾篇文章中的一個 strace指令用法

同時對于core.pid檔案的調試我也補充一下, 其中>>表示指令提示符

>>gdb JAVA_HOME/bin/java  core.pid   

>>bt  

bt後就可以看到生成core.pid檔案時,系統正在執行的一個操作,例如是哪個so檔案正在執行等。

好了說了這麼多,上面都是怎麼生成java

運作期DUMP檔案的,接下來我們就進入分析階段,為了分析這個dump出的檔案,需要将這個檔案弄到你的分析程式所在的機器上,例如可以是

windows上,linux上,這個和你使用的分析工具以及使用的作業系統有關。不管使用什麼系統,總是需要把生産環境下打出的dump檔案搞到你的分

析機器上,由于dump出的檔案經常會比較大,例如達到2G,這麼大的檔案不是很好的從生産環境拉下來,是以使用FTP的方式把檔案拖到分析機器上,同時

由于單個檔案很大,是以為了快速的将檔案下載下傳到分析機器,我們可以使用分而治之的思想,先将檔案切割為小檔案下載下傳,然後在合并為一個大檔案即可,還好

linux提供了很友善的工具,例如使用如下指令

$ split -b 300m heap.bin   

 $ cat x* > heap.bin  

在上面的 split 指令行中的 “300m” 表示分割後的每個檔案為 300MB,“heap.bin” 為待分割的dump檔案,分割後的檔案自動命名為 xaa,xab,xac等

cat 指令可将這些分割後的檔案合并為一個檔案,例如将所有x開頭的檔案合并為heap.bin

如果我們是利用一個中間層的FTP伺服器來儲存資料的,那麼我們還需要連接配接這個FTP伺服器把合并後的檔案拉下來,在windows下我推薦使用一個工具,速度很快而且簡單,

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

好了分析的檔案終于經過一翻周折到了你的分析機器上,現在我們就可以使用分析工具來分析這個dump出的程式了,這裡我主要是分析記憶體的問題,是以我說下我選擇的記憶體分析工具,我這裡使用的是開源的由SAP 和IBM 支援的一個記憶體分析工具

Memory Analyzer (MAT)

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

我建議下載下傳 Stand-alone Eclipse RCP 版本,不要裝成eclipse的插件,因為這個分析起來還是很耗記憶體。

下載下傳好了,解壓開來就可以直接使用了(基于eclipse的),打開以後,在菜單

欄中選擇打開檔案,選擇你剛剛的dump檔案,然後一路的next就可以了,最後你會看到一個報告,這個報告裡會告訴你可能的記憶體洩露的點,以及記憶體中對

象的一個分布,關于mat的使用請參考官方說明,當然你也可以自己徜徉在學習的海洋中 。

對于dump檔案的分析還可以使用jdk中提供的一個jhat工具來檢視,不過這個很耗記憶體,而且預設的記憶體大小不夠,還需要增加參數設定記憶體大小才能分析出,不過我看了下分析出的結果不是很滿意,而且這個用起來很慢。還是推薦使用mat 。