生產(chǎn)環(huán)境中,尤其是吃大內(nèi)存的JVM,一旦出現(xiàn)內(nèi)存泄露等問題是非常容易引發(fā)OutofMemory的,如果沒有一個好的工具提供給開發(fā)人員定位問題和分析問題,那么這將會是一場 噩夢 。目前JDK其實自帶有一些內(nèi)存泄露分析工具專門用于幫助開發(fā)人員定位內(nèi)存泄露等問題,但是這些工具往往并不是能夠滿足一些現(xiàn)狀,這里筆者所指的現(xiàn)狀更多是迅速、便捷、高效的定位出問題,方便開發(fā)人員迅速進行調(diào)整。
jmap是什么?簡單來說,jmap是JDK自帶的一種用于生成內(nèi)存鏡像文件的工具,通過該工具,開發(fā)人員可以快速生成dump文件。開發(fā)人員可以使用命令“jmap -help”查看jmap的常用命令,如下所示:
Usage: jmap [option] <pid> (to connect to running process) jmap [option] <executable <core> (to connect to a core file) jmap [option] [server_id@]<remote server IP or hostname> (to connect to remote debug server)where <option> is one of: <none> to print same info as Solaris pmap -heap to print java heap summary -histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects -permstat to print permanent generation statistics -finalizerinfo to print information on objects awaiting finalization -dump:<dump-options> to dump java heap in hprof binary format dump-options: live dump only live objects; if not specified, all objects in the heap are dumped. format=b binary format file=<file> dump heap to <file> Example: jmap -dump:live,format=b,file=heap.bin <pid> -F force. Use with -dump:<dump-options> <pid> or -histo to force a heap dump or histogram when <pid> does not respond. The "live" suboption is not supported in this mode. -h | -help to print this help message -J<flag> to pass <flag> directly to the runtime system
在此大家需要注意,jmap工具有一部分命令僅限于Linux和Solaris平臺,而Windows平臺下能夠使用的命令只有“jmap -histo<pid>”和“jmap -dump:<dump-options><pid>”。不過一般來說,使用命令“jmap -dump:<dump-options><pid>”生成dump文件應該是最常用的命令之一,由于生成dump文件時比較耗時的,因此大家需要耐心等待,尤其是大內(nèi)存鏡像生成dump文件則需要耗費更長的時間來完成。
MAT(Memory Analyzer Tool)工具是eclipse的一個插件,使用起來非常方便,尤其是在分析 大內(nèi)存的dump文件時,可以非常直觀的看到各個對象在堆空間中所占用的內(nèi)存大小、類實例數(shù)量、對象引用關(guān)系、利用OQL對象查詢,以及可以很方便的找出對象GC Roots的相關(guān)信息,當然最吸引人的還是能夠快速為開發(fā)人員生成內(nèi)存泄露報表,方便定位問題和分析問題。
MAT工具的下載地址為: http://www.eclipse.org/mat/downloads.php
MAT插件的下載地址為: http://download.eclipse.org/mat/1.3/update-site/
筆者所使用的MAT工具的版本為最新的1.4.0,為了避免在實際使用過程中出現(xiàn)一些不必要的異常情況,筆者建議大家使用與筆者相同版本版本的MAT工具分析dump文件。
只要確保機器上成功裝有JDK并配置好相關(guān)的環(huán)境變量后,運行“MemoryAnalyzer-1.4.0.20140604-win32.win32.x86\mat\”目錄下的MemoryAnalyzer.exe即可成功啟動MAT工具。
當大家成功下載和安裝好MAT后,接下來要做的事情就是使用jmap+MAT工具一起進行內(nèi)存泄露工作的分析。首先筆者先準備一段測試代碼,如下所示:
/** * -server -Xms1024m -Xmx1024m -Xmn384m -XX:+UseParallelOldGC * -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails * -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:/heap.bin */public class GCTest { public static void main(String[] args) { final int _1mb = 1024 * 1024; byte[] value1 = new byte[_1mb * 100]; byte[] value2 = new byte[_1mb * 100]; byte[] value3 = new byte[_1mb * 100]; new Thread() { public void run() { byte[] value4 = new byte[_1mb * 400]; } }.start(); byte[] value5 = new byte[_1mb * 200]; }}
在上述代碼示例中,具體的VM參見類注釋,而選項“-XX:+HeapDumpOnOutOfMemoryError ”和-“XX:HeapDumpPath”所代表的含義就是當程序出現(xiàn)OutofMemory時,將會在相應的目錄下生成一份dump文件,而如果不指定選項“XX:HeapDumpPath”則在當前目錄下生成dump文件。在此大家需要注意,盡管不借助jmap工具,MAT工具也能夠直接生成dump文件,但是考慮到生產(chǎn)環(huán)境中幾乎不可能在線對其進行分析,大都是采用離線分析,因此使用jmap+MAT工具是最常見的組合。
當上述程序執(zhí)行時,必然會觸發(fā)OutofMemory,然后在所指定的目錄下找到生成的dump文件后,我們便可以通過MAT工具來進行分析了。當成功啟動MAT后,通過菜單選項“File->Open heap dump...”打開指定的dump文件后,將會生成Overview選項,如圖1-1所示:
圖1-1 Overview選項
在Overview選項中,以餅狀圖的形式列舉出了程序內(nèi)存消耗的一些基本信息,其中每一種不同顏色的餅塊都代表了不同比例的內(nèi)存消耗情況。如果說需要定位內(nèi)存泄露的代碼點,我們可以通過Dominator Tree菜單選項來進行排查(MAT工具僅僅只是一個輔助,分析OutofMemory并不存在一個固定的方式和準則,因此仔細觀察和分析才能夠找到問題所在),如圖1-2所示:
圖1-2 Dominator Tree選項
就這樣吧,懶得寫了。
聯(lián)系客服