【Android 內存優化】使用 Memory Analyzer ( MAT ) 工具分析內存 ( MAT 工具使用 | 最大對象 | 類實例個數 | 引用與被引用 | GC Roots 最短鏈 )



內存泄漏原理 : 長生命週期對象 , 持有短生命週期對象的引用 , 並且是強引用持有 , GC 無法釋放該短生命週期對象引用 , 造成 OOM ;

Android Profiler 工具參考官方文檔 : 使用 Memory Profiler 查看 Java 堆和內存分配


使用 Memory Analyzer ( MAT ) 內存分析工具分析內存快照 , 首先要將內存快照文件 , 轉化成 MAT 工具能識別的文件 , 然後使用 MAT 工具進行分析 ;


在博客 【Android 內存優化】Android Profiler 工具常用功能 ( 監測內存 | 內存快照 ) 中保存了內存快照文件 memory-20200625T145636.hprof , 要使用 MAT 工具分析該內存快照 , 需要先將該文件轉換成爲 MAT 標準的文件格式 ;


在博客 【Android 內存優化】使用 Memory Analyzer ( MAT ) 工具分析內存 ( hprof 文件轉換 | MAT 工具下載 | MAT 工具使用 ) 中轉換了 MAT 格式的內存快照 , 下載 Memory Analyzer ( MAT ) 內存分析工具 , 並在該工具中加載了 MAT 格式的文件 ;


本博客中開始在 Memory Analyzer ( MAT ) 內存分析工具 中分析內存快照 ;





一、 內存中最大的對象



內存中最大的對象 : Overview 中的餅圖中 , 列出了佔用最大內存的對象 ;

在這裏插入圖片描述





二、 查看每個類的對象實例的個數



1. 查看每個類的對象實例的個數 : 點擊 Histogram 直方圖 , 查看每個類實例個數 ;

在這裏插入圖片描述

2. Histogram 直方圖界面如下 : 其中列出了每個類對象個數 ;

在這裏插入圖片描述





三、 查看對象的引用與被引用



對象的引用與被引用 : 右鍵點擊某對象 , 選擇 List objects 選項 ;


① 查看該對象引用了哪些對象 : 選擇 with incoming reference 選項 ;

② 查看該對象被哪些對象引用 : 選擇 with outgoing reference 選項 ;

在這裏插入圖片描述





四、 查看對象到 GC Roots 的最短距離





1、 選擇 Merge Shortest Paths to GC Roots


查看對象到 GC Roots 的最短距離 : 在右鍵菜單中選擇 " Merge Shortest Paths to GC Roots " , 這裏就可以看到爲什麼對象可達性分析時 , 某些對象應該釋放 , 卻仍然存在與 GC Root 對象之間的引用鏈 ;

在這裏插入圖片描述



2、 GC Roots 與 GC 垃圾回收


存在與 GC Roots 引用鏈導致內存泄漏 : 該對象可能與 GC Root 對象不是直接引用 , 而是由其它對象簡介引用 , 導致存在這麼一條引用鏈 ;


具體的 GC 回收原理在 【Android 內存優化】Java 內存模型 ( Java 虛擬機內存模型 | 線程私有區 | 共享數據區 | 內存回收算法 | 引用計數 | 可達性分析 ) 博客中的可發行分析章節 , 有詳細的介紹 , 如果 GC Root 對象與某個對象之間有引用鏈 , 那麼該對象無法被 GC 回收 ;



3、 Merge Shortest Paths to GC Roots 各個選項簡介


Merge Shortest Paths to GC Roots 各個選項簡介 :

  • with all reference : 列出所有的引用 ;
  • exclude weak reference : 排除弱引用 ;
  • exclude soft reference : 排除軟引用 ;
  • exclude phantom reference : 排除虛引用 ;
  • exclude weak/soft reference : 排除弱引用和軟引用 ;
  • exclude all phantom/weak/soft etc. reference : 排除虛引用 , 弱引用 , 軟引用 ; 只查看強引用 ;


4、 查看對象強引用引用鏈


③ 查看強引用引用鏈 : 這裏選擇 exclude all phantom/weak/soft etc. reference 選項 , 只查看到 GC Roots 的強引用引用鏈 ;

在這裏插入圖片描述

該 AppCompatTextView 類有三個對象的引用鏈 :

在這裏插入圖片描述

  • MainActivity 引用了 SurfaceView 對象
    • SurfaceView 對象 中的引用了 ConstraintLayout 對象
      • ConstraintLayout 對象 引用了 View 對象
        • View 對象 引用了兩個 AppCompatTextView 對象

在這裏插入圖片描述

  • MainActivity 引用了 AppCompatDelegateImpl 對象
    • AppCompatDelegateImpl 對象引用了 ActionBarOverlayLayout 對象
      • ActionBarOverlayLayout 對象引用了 ActionBarContainer 對象
        • ActionBarContainer 對象引用了 Toolbar 對象
          • Toolbar 對象引用了 11 個 AppCompatTextView 對象

這樣就找到了是哪個類引用了我們要查找的目標對象 , 然後在對應代碼中查找爲什麼沒有釋放這個類 ;

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