上篇讲到handler 的内存泄漏问题。
那么这个泄漏问题是如何查出来的呢。。
首先 androidstudio 就提供 一个 运行时监听工具
Android Monitor
我们现在 Memory 块
这里面有4个按钮
1. 停止
2. 调用GC 开始回收
3. dump heap(dump下堆信息,里面存在一堆对象的信息)
4. start allocation dump(还没用到带补充)
先确定是否存在泄漏
一开始 我们打开app后,在做某个操作 比如 狂打开某个activity 然后关闭 再打开等,观察内存的变化,这个时候 内存应该会不断的飙高,然后到达一个阀值会降下来(由系统决定,认为内存紧张的时候会调用GC 去回收)。如果这个时候我们去 按一下 第二个按钮 让GC 去回收,记下当前的 内存值 比如 60M,然后在做重复的操作(比如 再狂打开 activity,再关闭)看到 内存涨了 到80M,这个时候 再按 gc回收,发现他么的 内存还是 80 或者 根本没有降下来多少,之后的狂操作内存一直涨基本 可以确定存在泄漏了
分析哪里里泄漏
使用 dump heap ,会dump 出 堆里的信息。 dump完后 android studio 会出现下图
但是 这个并不好用。。分析看的蛋疼,所以我们使用MAT 这个工具来分析,但是要使用此工具需要导出他使用 .hprof 文件。在这里导出
这个时候就可以使用MAT 工具打开。查看,
先去下载自己对应系统的 MAT
然后使用mat 打开 刚刚导出的hropf,得到下图
我们主要使用 Histogram 这个功能来查看 堆里的对象
可以看到里面每个类型的对象
可以在 classname 中用正则表达式 筛选出 对应的类,比如我们现在怀疑是 DraeeView泄漏了,就把DraeeView的具体包名输入进去筛选出来,可以看到他 现在在堆里对应的对象数量。
发现现在有 9 个对象 ,而现在可以通过 右键 merage shortest Patch to GC Root 看它是GC root可达性,并且通过这个就可以观察到他的引用链,找出到底是那里有引用到啊并keep住此对象了
可以看到有两个引用链,然而第一个引用链。有8个对象被引用住。
其实这个时候 基本可以看出来是哪里出现了引用泄漏,这个根据自己对项目的判断。这里是否存在不合理的引用。从而判断出是否已经是泄漏了。
MAT 还有其他功能有待补充。