本篇文章給大家分享的是有關(guān)內(nèi)存分析工具M(jìn)AT的使用方法,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的保康網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
工欲善其事必先利其器,學(xué)會(huì)使用工具也是一種本領(lǐng)。本篇文章就把自己之前工作中用到的一個(gè)內(nèi)存分析工具給大家介紹下。
內(nèi)存分析工具M(jìn)AT(Memory Analyzer Tool)是一款 JVM 的內(nèi)存分析工具,在實(shí)際的工作中可以幫助我們解決生成上內(nèi)存占用過高等問題。
我之前用 MAT 是在 eclipse上使用,前者是后者的一個(gè)插件。后來換到 IDEA 才知道原來 MAT 也有獨(dú)立的可運(yùn)行版本。它的下載地址如下:
http://www.eclipse.org/mat/downloads.php
我們先準(zhǔn)備一段簡(jiǎn)單的代碼,這個(gè)代碼會(huì)導(dǎo)致 JVM 堆內(nèi)存溢出,方便我們演示 MAT 的效果。
public static void main(String[] args) throws InterruptedException {
Map<String,Tom> map = new HashMap<String,Tom>();
int counter = 1;
while(true) {
Thread.sleep(10);
Tom tom = new Tom();
String [] friends = new String[counter];
for (int i = 0; i < friends.length; i++) {
friends[i] = "friends"+i;
}
tom.setAge(counter);
tom.setName("tom"+counter);
tom.setFriends(friends);
map.put(tom.getName(),tom);
if(counter%100==0)
System.out.println("put"+counter);
counter++;
}
}
很好理解的一段代碼,一個(gè)無限循環(huán),不斷的往map里添加名為Tom的對(duì)象,而且每次循環(huán)new出來的對(duì)象的friends屬性還在不斷的擴(kuò)大。
然后我們使用啟動(dòng)下面這個(gè)啟動(dòng)參數(shù)運(yùn)行代碼,
-Xms200m -Xmx200m -XX:+HeapDumpOnOutOfMemoryError
參數(shù)指定了堆內(nèi)存大小是200m,這個(gè)大小我們的測(cè)試代碼很快就會(huì)用完,然后報(bào)錯(cuò)。
啟動(dòng)代碼,運(yùn)行一段時(shí)間后報(bào)錯(cuò)如下,
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid1398.hprof ...
Heap dump file created [239632332 bytes in 0.865 secs]
從這個(gè)報(bào)錯(cuò)我們可以獲取幾個(gè)信息,首先是錯(cuò)誤類型是內(nèi)存溢出,原因是超出了GC的限制。
其次,我們看到程序出錯(cuò)時(shí)的內(nèi)存快照 dump 到了一個(gè)名為 java_pid1398.hprof 的文件中了。這個(gè)文件就是可以用于 MAT 工具分析的dump文件。
除了上面的通過 -XX:+HeapDumpOnOutOfMemoryError 參數(shù)來dump內(nèi)存文件之外, 還可以通過 jmap 命令來導(dǎo)出的內(nèi)存快照。這里不做詳述了。
我們現(xiàn)在根據(jù) MAT 的分析,從幾個(gè)維度來分析下代碼中的問題。
MAT 工具打開前面的 dump 文件,會(huì)先看到下面這種圖,
從預(yù)覽圖,可以看到有個(gè)應(yīng)用占用了總的堆內(nèi)存的大部分,高達(dá)184M(程序運(yùn)行分配的堆內(nèi)存是200M)。說明這個(gè)應(yīng)用肯定有問題,值得我們繼續(xù)往下分析。
我們先看看工具給我們的一個(gè)判斷,找到 Leak Suspects,點(diǎn)擊去。
從描述上看到,主線程有個(gè)本地變量占用了很大內(nèi)存,這個(gè)變量是 HashMap 的實(shí)例。
哈哈,根據(jù)上面的代碼,不得不說 MAT 還是很牛叉的,對(duì)于內(nèi)存泄漏點(diǎn)定位的很準(zhǔn)確。
不過有時(shí)候,我們還是需要手動(dòng)分析下我們還是回到之前的預(yù)覽頁面,找到 Histogram 點(diǎn)進(jìn)去,如下圖:
shallow heap 指的是對(duì)象自身占用的內(nèi)存大小,不包括它引用的對(duì)象。
針對(duì)非數(shù)組類型的對(duì)象,它的大小就是對(duì)象與它所有的成員變量大小的總和。當(dāng)然這里面還會(huì)包括一些java語言特性的數(shù)據(jù)存儲(chǔ)單元。
針對(duì)數(shù)組類型的對(duì)象,它的大小是數(shù)組元素對(duì)象的大小總和。
我們看到排在前面的是占用內(nèi)存比較多的,
char[] 這個(gè)明顯是String里引用造成的(string里用char[] 存儲(chǔ)數(shù)據(jù)),我們之間來看String是被誰引用的,
很清晰,Tom對(duì)象的friends屬性消耗了很多內(nèi)存。
這里說明下,
with incoming references 表示的是 當(dāng)前查看的對(duì)象,被外部應(yīng)用
with outGoing references 表示的是 當(dāng)前對(duì)象,引用了外部對(duì)象
同理,我們可以繼續(xù)分析下面幾個(gè)類,最終都會(huì)定位到內(nèi)存吃緊的原因是 hashmap 里短時(shí)間塞了大量的 Tom 對(duì)象撐爆了內(nèi)存。
以上就是內(nèi)存分析工具M(jìn)AT的使用方法,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站名稱:內(nèi)存分析工具M(jìn)AT的使用方法
標(biāo)題URL:http://m.rwnh.cn/article36/jepesg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、軟件開發(fā)、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、Google、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)