虽然现在有了leakcanary 这个神器,能够检测出内存泄漏。但是还是抱着手动去检测并且做一次从头到尾的分析。所以就拿现有公司的app去做了一次首页内存泄漏的检测 并且发现了内存泄漏都地方。以下记录下分析过程.


Markdown Extra 定义列表语法:

界面操作 首页是一个viewpager 连续滑动几页然后点击内存回收发下内存大小没有发生任何变化(点击1这个地方)

android 查内存泄漏 android检测内存泄露_内存泄漏


由此可以判断Fragment发生内存泄漏了。接下来就是分析内存泄漏了。

分析 点击2这个地方内存分析工具会裆出当前app的内存情况

android 查内存泄漏 android检测内存泄露_内存泄漏_02


然后出现下面的图片的样子


android 查内存泄漏 android检测内存泄露_内存泄漏_03


然后点击3这个地方选择package方式


由于咋们能大体知道是什么界面发生的内存泄漏,所以咋们只需要关心内存泄漏的界面即可(我只在首页的fragment上进行了滑动)


这样就会以包名的方式列举出内存的对象


android 查内存泄漏 android检测内存泄露_内存优化_04


可以看到5这个Fragment(viewpager上的)在内存中出现了7个这显然不对应为我的pageadapter使用的是statepageadapter。


如果用studio自带的分享工具的话需要一层一层耳朵去找里面对象的引用关系如果depth不为0的话表示不能被回收掉。这样分享不太方便所以借助Mat工具来分析的话会非常方便切直观。

导出heap dump文件 点击7这个地方导出文件

android 查内存泄漏 android检测内存泄露_android_05


导出的文件是不能直接被Mat工具识别的需要用androidSdk中的工具转换一下


android 查内存泄漏 android检测内存泄露_内存优化_06


转换好后就可以使用Mat工具进行分析了(Mat是MemoryAnalyzer的缩写网上可以去下载这个工具)

用Mat工具分析 打开Mat工具并用Map打开刚才转换后的hporf文件

android 查内存泄漏 android检测内存泄露_分析工具_07


点击8(以支配树方式显示 我喜欢用这种方式看)


然后再点击9 以package方式来显示对象 和前面android studio分析工具差不多


android 查内存泄漏 android检测内存泄露_分析工具_08


然后右键点击内存泄漏的类


android 查内存泄漏 android检测内存泄露_android_09


手动回收弱引用等情况


android 查内存泄漏 android检测内存泄露_android_10


android 查内存泄漏 android检测内存泄露_分析工具_11

内存泄漏一般都是由某个方法引用了context且生命周期大于Context导致其无法被释放。Mat工具在最后一步都会给出是什么方法

比如我工程里的内存泄漏通过提示就能看出是添加OnGlobaleChangeListener时造成的,只需要去代码里找添加这个监听的地方就能解决了

android 查内存泄漏 android检测内存泄露_分析工具_12