離線分析java內存

如題,我這裏簡單說下我現在離線分析java內存的方式,所謂離線,就是需要 dump出正在運行的java系統中的一些運行時堆棧數據,然後拿到線下來分析,分析可以包括內存,線程,GC等等,同時不會對正在運行的生產環境的機器 造成很大的影響,對應着離線分析,當然是在線分析了,這個我在後面會嘗試下,因爲離線分析有些場景還是模擬不出來,需要藉助LR來模擬壓力,查看在線的 java程序運行情況了。

 

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

Java代碼 複製代碼

  1. ps -aux   

  2.   

  3. ps -ef | grep java  

 

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

 

Java代碼 複製代碼

  1. /JAVA_HOME/bin/jps  

 

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

 

Java代碼 複製代碼

  1. 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 ),這裏我在補充點

 

 

Java代碼 複製代碼

  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]  

 

需要說明一下,使用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轉換不成功的同學,可以使用如下命令來分析跟蹤命令的執行軌跡,例如使用

 

Java代碼 複製代碼

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

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


同時對於core.pid文件的調試我也補充一下, 其中>>表示命令提示符

 

Java代碼 複製代碼

  1. >>gdb JAVA_HOME/bin/java  core.pid   

  2.   

  3. >>bt  

 

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

 

好了說了這麼多,上面都是怎麼生成java 運行期DUMP文件的,接下來我們就進入分析階段,爲了分析這個dump出的文件,需要將這個文件弄到你的分析程序所在的機器上,例如可以是 windows上,linux上,這個和你使用的分析工具以及使用的操作系統有關。不管使用什麼系統,總是需要把生產環境下打出的dump文件搞到你的分 析機器上,由於dump出的文件經常會比較大,例如達到2G,這麼大的文件不是很好的從生產環境拉下來,因此使用FTP的方式把文件拖到分析機器上,同時 由於單個文件很大,因此爲了快速的將文件下載到分析機器,我們可以使用分而治之的思想,先將文件切割爲小文件下載,然後在合併爲一個大文件即可,還好 linux提供了很方便的工具,例如使用如下命令

 

Java代碼 複製代碼

  1. $ split -b 300m heap.bin   

  2.   

  3.  $ 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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章