Android MAT分析内存

本篇文章是第一次分析 App 内存的一次记录,使用了一些简单的 adb 命令以及 MAT 工具对内存文件进行分析,对简单的一些内存问题进行了举例说明。
这篇文章第一次发布在 CSDN ,由于 CSDN 已长期不维护,所以迁移到此处。 最近还会对内存进行深入研究,所以自己也顺带看看以前的青涩思路。

内存分析

使用adb dumpsys 命令
adb是一个非常强大的工具,使用adb查看应用程序内存使用情况可按如下格式在命令行里查看内存使用情况:
adb shell dumpsys meminfo <package_name>

还有些有用的命令

  1. adb shell dumpsys activity—————查看ActvityManagerService 所有信息
  2. adb shell dumpsys activity activities———-查看Activity组件信息
  3. adb shell dumpsys activity services———–查看Service组件信息
  4. adb shell dumpsys activity providers———-产看ContentProvider组件信息
  5. adb shell dumpsys activity broadcasts——–查看BraodcastReceiver信息
  6. adb shell dumpsys activity intents————–查看Intent信息
  7. adb shell dumpsys activity processes———查看进程信息

其中,package_name 也可以换成程序的pid,pid可以通过 adb shell top | grep app_name 来查找

重点关注如下几个字段:
(1) Native/Dalvik 的 Heap 信息
具体在上面的第一行和第二行,它分别给出的是JNI层和Java层的内存分配情况,如果发现这个值一直增长,则代表程序可能出现了内存泄漏。

(2) Total 的 PSS 信息
这个值就是你的应用真正占据的内存大小,通过这个信息,你可以轻松判别手机中哪些程序占内存比较大了。

命令输入后还有以下信息:
图片

  • 横竖屏或者切屏观察activity数目变化,Activity发生重建且上面标记处数目增加,那么就表示该activity未被回收,存在内存泄漏。 *

    图片

    导出的文件并不能直接被MAT工具解析,需要用工具转换。工具地址:D:\sdk\tools\hprof-conv.exe
    命令输入:

    D:\sdk\tools\hprof-conv.exe        D:\mat_any\com.lenovo.tabletstore.hprof     D:\mat_any\my.hprof
    工具路径--->直接导出文件的路径--->希望转换后存储文件名及路径
    

    接下来用MAT分析该文件,下载地址文档介绍

内存泄漏分析

通过对网上资料整理,发现还是下面的方法比较简洁好用

图片

打开MAT找到标记按钮,输入查找数据库指令

select * from instanceof android.app.Activity

按Ctrl + F5或者! 或者 F5

操作可以参考 这篇文章 :使用Android studio分析内存泄露

个人建议:
如果搜索出来的同一个activity只有一个(前提是确定该activity确实发生多次重建),那么可以忽略,但是最好还是看下是否有自己熟悉的泄漏;如果存在多个相同的activity,那么理论上 这个字段小的 是应该被回收的Activity。所以要选中这些应被回收而未被回收的Activity进行上述的操作 右键–>Path To Gc Roots –> exclude weak/soft reference

提供本人遇到的几个泄漏问题:

<1> Context 被引用,未被回收,所以在能用ApplicationContext的地方尽量使用ApplicationContext
使用场景参考 http://blog.csdn.net/lmj623565791/article/details/40481055 Android Context 上下文 你必须知道的一切

<2> Listener 自己添加的 需要自己去解除引用
图片

图片

<3> 使用弱引用时应该注意返回弱引用中取出的对象,将强引用释放,而不是直接返回强引用对象

图片
图片

最后需要根据分析的结果去排查泄漏的地方,如果看不懂分析结果,可以自己拿到该对象去代码中排查,对每一个引用点进行细致分析,是否会存在异步问题导致比Activity生命周期存在时间长而产生内存泄漏,以及存储的集合是否需要手动清空等等…