欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

java中如何使用mat分析java堆

java中如何使用mat分析java堆,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

成都創(chuàng)新互聯(lián)主營英吉沙網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶App定制開發(fā),英吉沙h5重慶小程序開發(fā)搭建,英吉沙網(wǎng)站營銷推廣歡迎英吉沙等地區(qū)企業(yè)咨詢

MATmemory analyzer 的簡稱,它是一款功能強(qiáng)大的java堆內(nèi)存分析器,可以用來查找內(nèi)存泄露,以及查看內(nèi)存消耗的情況,可以在MAT官網(wǎng)進(jìn)行下載。

1. 初識(shí)

1.1 導(dǎo)出堆應(yīng)用快照

jmap、jconsole、jvisualvm 等工具可以導(dǎo)出java應(yīng)用程序的堆快照文件,MAT 也有該功能,如圖所示:

java中如何使用mat分析java堆

點(diǎn)擊“Accquire Heap Dump”菜單后,會(huì)彈出當(dāng)前java應(yīng)用程序列表,選擇要分析的應(yīng)用程序即可,如圖所示:

java中如何使用mat分析java堆

1.2 打開堆快照文件

除了直接在MAT中導(dǎo)出應(yīng)用程序的堆快照外,也可以通過“Open Heap Dump”來打開一個(gè)已有的堆快照文件。

如圖所示,顯示了正常打開堆快照文件后MAT的界面:

java中如何使用mat分析java堆

  • 在右側(cè)界面中,顯示了堆快照文件的大小、類、實(shí)例和ClassLoader的總數(shù)。

  • 在餅圖中,顯示了當(dāng)前堆快照中最大的對象。

  • 將鼠標(biāo)懸停在餅圖中,可以在左側(cè)的Inspector界面中,查看該對象的相應(yīng)信息。

  • 在餅圖中,單擊某對象,可以對選中的對象進(jìn)行更多操作。

1.3 查看所有類的內(nèi)存使用情況

如圖所示,在工具欄上單擊柱狀圖,可以顯示系統(tǒng)中所有類的內(nèi)存使用情況:

java中如何使用mat分析java堆

1.4 查看java線程

MAT 也可以查看java線程,如圖所示:

java中如何使用mat分析java堆

當(dāng)然,這里查看java層面的應(yīng)用線程,虛擬機(jī)的系統(tǒng)線程是無法顯示的。通過線程的堆棧,還可以查看局部變量的信息。如下圖所示,帶有 <local> 標(biāo)記的為當(dāng)前幀棧的局部變量,這部分信息可能存在缺失。

java中如何使用mat分析java堆

除此之外,MAT也可以查看詳細(xì)的線程堆棧信息:

java中如何使用mat分析java堆

由此打開thread_detail標(biāo)簽頁,可以清晰地看到線程堆棧信息:

java中如何使用mat分析java堆

1.4 查看對象的引用

MAT 的另外一個(gè)常用功能,是在各個(gè)對象的引用列表中交叉查看。對于一個(gè)給定對象,通過MAT可以找到引用當(dāng)前對象的對象,即入引用(Incomming References,以及當(dāng)前對象引用的對象,即出引用(Outgoing References,如圖所示:

java中如何使用mat分析java堆

2. 淺堆與深堆

淺堆(Shallow Heap)和深堆(Retained Heap)是兩個(gè)非常重要的概念,它們分別表示一個(gè)對象結(jié)構(gòu)所占用的內(nèi)存大小和一個(gè)對象被GC回收后,可以真實(shí)釋放的內(nèi)存大小。

淺堆是指一個(gè)對象所消耗的內(nèi)存。在32位系統(tǒng)中,一個(gè)對象引用會(huì)占據(jù)4字節(jié),一個(gè)int類型變量會(huì)占據(jù)4字節(jié),一個(gè)long類型變量會(huì)占8字節(jié),每個(gè)對象頭需要占8字節(jié)。根據(jù)堆快照格式不同,對象的大小可能會(huì)向8字節(jié)對齊。

根據(jù)堆快照格式不同,對象的大小可能會(huì)向8字節(jié)進(jìn)行對齊。以String對象為例,如下圖所示,顯示了String對象的幾個(gè)屬性。

  • String

    • value:char[]

    • offset:int

    • count:int

    • hash:int

3個(gè)int值共占12字節(jié),對象引用占用4字節(jié),對象頭8字節(jié),合計(jì)24字節(jié)。淺堆的大小只與對象的結(jié)構(gòu)有關(guān),與對象的實(shí)際內(nèi)容無關(guān)。也就是說,無論字符串的長度有多少,內(nèi)容是什么,淺堆的大小始終是24字節(jié)。

深堆(Retained Heap)的概念略微復(fù)雜。要理解深堆,首先需要了解保留集(Retained Set)。對象A的保留集指當(dāng)對象A被垃圾回收后,可以被釋放的所有的對象集合(包括對象A本身),即對象A的保留集可以被認(rèn)為是只能通過對象A被直接或間接訪問到的所有對象的集合。通俗地說,就是指僅被對象A所持有的對象的集合。深堆是指對象的保留集中所有的對象的淺堆大小之和。

注:淺堆指對象本身占用的內(nèi)存,不包括其內(nèi)部引用對象的大小。一個(gè)對象的深堆指只能通過該對象訪問到的(直接或間接)所有對象的淺堆之和,即對象被回收后,可以釋放的真實(shí)空間。

另外一個(gè)常用的概念是對象的實(shí)際大小。這里,對象的實(shí)際大小定義為一個(gè)對象所能觸及的所有對象的淺堆大小之和,也就是通常意義上我們說的對象大小。與深堆相比,似乎這個(gè)在日常開發(fā)中更為直觀和被人接受,但實(shí)際上,這個(gè)概念和垃圾回收無關(guān)。

如圖所示,顯示了一個(gè)簡單的對象引用關(guān)系圖,對象A引用了C和D,對象B引用了C和E。那么對象A的淺堆大小只是A本身,不含C和D,而A的實(shí)際大小為A、C、D三者之和。而A的深堆大小為A與D之和,由于對象C還可以通過對象B訪問到,因此不在對象A的深堆范圍內(nèi)。

java中如何使用mat分析java堆

3 支配樹

MAT 提供了一個(gè)稱為支配樹(Dominator Tree)的對象圖。支配樹體現(xiàn)了對象實(shí)例間的支配關(guān)系。在對象引用圖中,所有指向?qū)ο驜的路徑都經(jīng)過對象A,則認(rèn)為對象A支配對象B.如果對象A是離對象B最近的一個(gè)支配對象,則認(rèn)為對象A為對象B的直接支配者。支配樹是基于對象間的引用圖所建立的,它有以下基本性質(zhì):

  • 對象A的子樹(所有被對象A支配的對象集合)表示對象A的保留集(Reatined Set),即深堆。

  • 如果對象A支配對象B,那么對象A的直接支配者也支配對象B.

  • 支配樹的邊與對象引用圖的邊不直接對應(yīng)。

如圖所示,左圖表示對象引用圖,右圖表示左圖所對應(yīng)的支配樹。對象A和B由根對象直接支配,由于在到對象C的路徑中,可以經(jīng)過A,也可以經(jīng)過B,因此對象C的直接支配者也是根對象。對象F與對象D相互引用,因?yàn)榈綄ο驠的所有路徑必然經(jīng)過對象D,因此,對象D是對象F的直接支配者。而到對象D的所有路徑中,必然經(jīng)過對象C,即使是從對象F到對象D的引用,從根節(jié)點(diǎn)出發(fā),也是經(jīng)過對象C的,所以,對象D的直接支配者為對象C。

java中如何使用mat分析java堆

在MAT中,單擊工具欄上的對象支配樹按鈕,可以打開對象支配樹視圖:

java中如何使用mat分析java堆

注:在對象支配樹中,某個(gè)對象的子樹表示在該對象被回收后也將被回收的對象的集合。

4. MAT 堆分析案例解析

首先準(zhǔn)備案例代碼:

package jvm.chapter07;

import java.util.List;
import java.util.Vector;

/**
 * {這里添加描述}
 *
 * @author chengyan
 * @date 2019-11-15 11:01 下午
 */
public class Demo04 {
    private static List<WebPage> webPages = new Vector<>();
    public static void createWebPages() {
        for(int i = 0; i < 100; i++) {
            WebPage webPage = new WebPage();
            webPage.setUrl("http:www." + Integer.toString(i) + ".com");
            webPage.setContent(Integer.toString(i));
            webPages.add(webPage);
        }
    }

    public static void main(String[] args) {
        createWebPages();
        Student student3 = new Student(3, "billy");
        Student student5 = new Student(5, "alice");
        Student student7 = new Student(7, "taotao");
        for(int i = 0; i < webPages.size(); i++) {
            if(i % student3.getId() == 0) {
                student3.visit(webPages.get(i));
            }
            if(i % student5.getId() == 0) {
                student5.visit(webPages.get(i));
            }
            if(i % student7.getId() == 0) {
                student7.visit(webPages.get(i));
            }
        }
        webPages.clear();
        System.gc();
    }

}

class Student {
    private int id;

    private String name;

    private List<WebPage> history = new Vector<>();

    public void visit(WebPage webPage) {
        history.add(webPage);
    }

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<WebPage> getHistory() {
        return history;
    }

    public void setHistory(List<WebPage> history) {
        this.history = history;
    }
}

class WebPage {
    private String url;

    private String content;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

可以看到,在 Demo04.java 類中,首先創(chuàng)建了100個(gè)網(wǎng)址,為了閱讀方便,這里的網(wǎng)址均以數(shù)字作為域名,分別為0~99.之后,程序創(chuàng)建了3名學(xué)生:billy、alice和taotao.他們分別瀏覽了能被3、5、7整除的網(wǎng)址。在程序運(yùn)行后,3名學(xué)生的history中應(yīng)該保存他們各自訪問過的網(wǎng)址?,F(xiàn)在,希望在程序退出前,得到系統(tǒng)的堆信息并加以分析,查看每個(gè)學(xué)生實(shí)際訪問的網(wǎng)址。

使用如下參數(shù)運(yùn)行程序:

-XX:+HeapDumpBeforeFullGC -XX:HeapDumpPath=./stu.hprof
4.1 使用MAT打開堆文件

使用MAT打開產(chǎn)生的stu.hprof文件,如圖所示:

java中如何使用mat分析java堆

右側(cè)界面中,顯示了堆快照文件的大小、類、實(shí)例和ClassLoader的總數(shù)。在右側(cè)的餅圖中,顯示了當(dāng)前堆快照中最大的對象。將鼠標(biāo)懸停在餅圖中,可以在左側(cè)的Inspector界面中,查看該對象的相應(yīng)信息。在餅圖中單擊某對象,可以對選中的對象進(jìn)行更多的操作。

4.2 查看線程

在線程視圖中可以通過main線程找到3名學(xué)生的引用,如圖所示,可以清晰看到三個(gè)對象的學(xué)生名。除了對象名稱,MAT還給出了淺堆大小和深堆大小??梢钥吹?,所有的Student類的淺堆統(tǒng)一為24字節(jié),和他們持有的內(nèi)容無關(guān)。而深堆大小各不相同,這和每名學(xué)生訪問的網(wǎng)址有關(guān)。

java中如何使用mat分析java堆

當(dāng)然,這里查看Java層面的應(yīng)用線程,對于虛擬機(jī)的系統(tǒng)線程是無法顯示的。通過線程的堆棧,還可以查看局部變量的信息。帶有 <local> 標(biāo)記的,就為當(dāng)前幀棧的局部變量,這部分信息可能存在缺失。

4.3 查看對象的出引用

為了獲得taotao同學(xué)訪問過的網(wǎng)址,可以在taotao的記錄中通過“出引用”(Outgoing References)查找,可以找到由taotao可以觸及的對象,也就是他們訪問過的網(wǎng)址,如圖所示:

java中如何使用mat分析java堆

訪問過的網(wǎng)址如下:

java中如何使用mat分析java堆

可以看到堆中完整顯示了所有taobao同學(xué)的history中的網(wǎng)址。

4.4 查看入引用

如果現(xiàn)在希望查看哪些同學(xué)訪問了“http://www.0.com”,則可以在對應(yīng)的WebPage對象中通過“入引用”(Incoming References)查找:

java中如何使用mat分析java堆

顯然,這個(gè)網(wǎng)址被3名學(xué)生都訪問過了。

java中如何使用mat分析java堆

4.5 查看支配樹

如圖所示,顯示了Main Thread的對象支配樹。被Student對象直接支配的對象,均放在該對象下的history中,即當(dāng)Student對象被回收時(shí),也會(huì)一并回收該對象所支配的所有對象。

另外,還有一部分WebPage的父節(jié)點(diǎn)是Thread,這表明這部分的WebPage同時(shí)被多個(gè)Student對象持有,例如,84能同時(shí)被3和7整除,這表明該對象會(huì)同時(shí)被billytaobao持有,當(dāng)billytaobao其中之一并回收時(shí),該對象并不會(huì)回收,因此不會(huì)單獨(dú)顯示在billytaobaohistory中。

java中如何使用mat分析java堆

4.6 查看所有類的內(nèi)存使用情況

在工具欄上單擊柱狀圖,可以顯示系統(tǒng)中所有類的內(nèi)存使用情況。圖為系統(tǒng)內(nèi)所有類的統(tǒng)計(jì)信息,包含類的實(shí)例數(shù)量和占用的空間。

java中如何使用mat分析java堆

為了方便查看,柱狀圖還提供了根據(jù)Class Loader和包對類進(jìn)行排序。如下圖是按照包排序的柱狀圖輸出。

java中如何使用mat分析java堆

看完上述內(nèi)容,你們掌握java中如何使用mat分析java堆的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)站名稱:java中如何使用mat分析java堆
文章位置:http://chinadenli.net/article10/gdoggo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、、Google、品牌網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)