jmap的使用以及內存溢出分析


一、jmap的使用以及內存溢出分析

   前面通過jstat可以對jvm堆的內存進行統計分析,而jmap可以獲取到更加詳細的內容,如:內存使用情況的匯總、對內存溢出的定位與分析

1、查看內存使用情況

jmap -heap 29720

  

2、查看內存中對象數量及大小  

   #查看所有對象,包括活躍以及非活躍的  jmap ‐histo <pid> | more
  #查看活躍對象  jmap ‐histo:live <pid> | more
#查看活躍對象
jmap -histo:live 29720 | more
  
  對象說明:
    B byte
    C char
    D double
    F float
    I int
    J long
    Z boolean
    [ 數組,如[I表示int[]
    [L+類名 其他對象

3、將內存使用情況dump到文件中

  有些時候我們需要將jvm當前內存中的情況dump到文件中,然后對它進行分析,jmap也是支持dump到文件中的。
#用法: jmap -dump:format=b,file=dumpFileName <pid>
jmap -dump:format=b,file=../tmp/dump.dat 29720
  

   

4、通過jhat對dump文件進行分析

   我們將jvm的內存dump到文件中,這個文件是一個二進制的文件,不方便查看,這時我們可以借助於jhat工具進行查看。
#用法: jhat -port <port> <file>
jhat -port 29729 ../tmp/dump.dat
   打開瀏覽器進行訪問:http://localhost:29729/
  
  在最后面有OQL查詢功能:

   

  點擊下面選項:

  

   進入頁面,輸入下面語句查詢字符串大於10000,點擊Execute按鈕,查詢結果:

select s from java.lang.String s where s.value.length >= 10000

  

5、通過MAT工具對dump文件進行分析 

5.1  MAT工具介紹

  MAT(Memory Analyzer Tool),一個基於Eclipse的內存分析工具,是一個快速、功能豐 富的JAVA heap分析工具,它可以幫助我們查找內存泄漏和減少內存消耗。使用內存分析 工具從眾多的對象中進行分析,快速的計算出在內存中對象的占用大小,看看是誰阻止 了垃圾收集器的回收工作,並可以通過報表直觀的查看到可能造成這種結果的對象。

5.2  下載安裝  

 
  

  解壓后得到的文件列表:

   

5.3  使用

  ①雙擊啟動 MemoryAnalyzer.exe應用程序

    

  ②打開一個dump文件

     

  ③操作如圖兩步

    

  ④查看Overview

     

  ⑤查看Histogram

    

  ⑥查看對象以及它的依賴  dominator_tree

     

  ⑦查看可能存在內存泄露的分析

      

二、內存溢出的定位與分析 

  內存溢出在實際的生產環境中經常會遇到,比如,不斷的將數據寫入到一個集合中,出 現了死循環,讀取超大的文件等等,都可能會造成內存溢出。
如果出現了內存溢出,首先我們需要定位到發生內存溢出的環節,並且進行分析,是正 常還是非正常情況,如果是正常的需求,就應該考慮加大內存的設置,如果是非正常需 求,那么就要對代碼進行修改,修復這個bug。
  首先,我們得先學會如何定位問題,然后再進行分析。如何定位問題呢,我們需要借助 於jmap與MAT工具進行定位分析。 

1、模擬內存溢出 

   編寫代碼,向List集合中添加100萬個字符串,每個字符串由1000個UUID組成。如果程序能夠正常執行,最后打印ok
package com.zn;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class TestJvmOutOfMemory {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i < 10000000; i++) {
            String str = "";
            for (int j = 0; j < 1000; j++) {
                str += UUID.randomUUID().toString();
            }
            list.add(str);
        }
        System.out.println("ok");
    }
}

2、設置VM options參數  

-Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
  

3、運行測試

  

4、當發生內存溢出時,會dump文件到java_pid65828.hprof

    

5、導入到MAT工具中進行分析

  
  可以看到,有87.99%的內存由Object[]數組占有,所以比較可疑。
  分析:這個可疑是正確的,因為已經有超過90%的內存都被它占有,這是非常有可能出 現內存溢出的。

6、查看詳情 

  可以看到集合中存儲了大量的uuid字符串

  

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM