Mac Android 内存泄漏分析 实战演练
虚的概念就不讲了,自己去网上搜,一大堆。 这里来一次实战演练
简书上有一篇讲解 内存泄漏分析 的文章,总结的很到位,由浅入深,比较全面。建议结合起来阅读
预备知识:
1、Mac版 MAT 官网下载地址: (也可以自行百度)
http://www.eclipse.org/downloads/download.php?file=/mat/1.7/rcp/MemoryAnalyzer-1.7.0.20170613-macosx.cocoa.x86_64.zip
2、 adb 重启命令
adb kill-server
adb start-server
开始正题:
1、运行 Android_SDK/tools/monitor, 界面如下。 如果启动报错,请关闭Android Studio、并保证手机正确连接电脑调试、adb正常运行.
当然 有些版本的 Android Studio 中也有快捷入口,自己去找
打开后 点击 红框中的按钮,稍等大约 十几秒到 几十秒时间 后,会生成后缀后 .hprof 文件,自己保存下来
2、转换格式,运行 sdk 目录 下的 Android_SDK/platform-tools/hprof-conv 可以执行文件,
输入命令:hprof-conv <空格> -z <空格> 你第1步得到的.hprof文件的路径 <空格> 格式转换后的文件名称
执行完成后,会在当前目录生成 bbbbbb 文件(名称可以自己修改),这个文件 就可以用 MAT 工具打开
3、下载MAC版本的 MAT 工具, 菜单->File->Open Heap Dump, 打开 bbbbb 文件
可选的文件格式 记得改为 All File, 所有文件都能选择
a、打开后,点击 第1个图标, 使用 histogram(翻译 柱状图) 格式打开, 方便查看 各个 类 的 实例分布情况
b、点击第2个位置输入框 ,可以按 类名 来查找 相应类的 实例分布。 这里可以看到 UserFavorFragment 类 有 3个实例, 共占用内存 672KB(不包含成员变量所引用的对象的内存),
4、分析
在第一行点 右键, 选择"Merge Shortest Paths to GC Roots"-> exclude weak/soft references , 可以查看 从 GCRoot 到这些 UserFavorFragment 实例的 最短路径, 并且 不考虑 软引用和弱引用, 因为这两种引用 不影响GC,不会发生 内存泄漏.
可以看到这3个实例 的 引用路径, 但只有 2条记录, 有2个实例是被 同一个类的不同实例引用
完全打开第2条记录,可以看到 到底 是经过 怎样的 依赖,导致 UserFavorFragment 不能被 GC回收, 找到不合理的引用,再从代码里查找 它是何时何处 被引用的 ,就能找到内存泄漏的 根本原因。 最后才是想办法 修改代码,解决内存漏泄.
注意:这篇 文章 ,我们是 已经明确知道 UserFavorFragment 发生了漏泄, 实际我们如何确定 到底哪一块位置 发生了泄漏,可以通过 缩小范围的 方式 来确实, 如:打开某个 Activity发现 内存瀑增,那尝试不加载 某一块业务逻辑,看看内存是否仍然暴增, 这样不断缩小范围 就能确定是哪一个 类 发生 泄漏.