【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 对象引用了 1 1 个 AppCompatTextView 对象

这样就找到了是哪个类引用了我们要查找的目标对象 , 然后在对应代码中查找为什么没有释放这个类 ;

猜你喜欢

转载自blog.csdn.net/han1202012/article/details/106961256