说明:如果只是单存的内存抖动,AndroidStudio的Memory Profiler就可以分析了,具体分析过程已经有很多文章说明了,这里就不赘述,接下来要说的是内存泄露的追查。
1.MAT下载
MAT 下载地址:https://www.eclipse.org/mat/downloads.php
下载版本:
Mac OSX (Mac/Cocoa/x86_64)
2.MAT安装和启动
下载完成,在Downloads目录下找到
MemoryAnalyzer-1.9.0.20190605-macosx.cocoa.x86_64.zip
。
解压文件,得到
mat.app
目录。移动到自己的目录下执行 /xxxxx/mat.app/Contents/MacOS/MemoryAnalyzer -data ./workspace
输入命令行 : /Users/mac/Desktop/mat/mat.app/Contents/MacOS/MemoryAnalyzer -data ./workspace
看到欢迎界面就是成功了。
这是一款用于内存分析的工具,主要可以对内存泄露(OOM之前)的问题进行分析和定位。配合Memory Profiler分析内存泄露导致的卡顿和线上偶发性的崩溃。
由于我们的app中有一些写的不合适的代码片段,导致内存的分配非常频繁,在频繁的分配和GC的情况下就会出现内存抖动。当我们使用static不注意的时候就很容易造成 对外部类的强引用,即使不调用不崩溃,但是由于static和app的生命周期相同,所以强引用的对象无法释放,导致内存无法清理,由于每一个app所分配的内存是有限的,所以就会导致内存泄露,当泄露到一定程度,剩余内存或者内存碎片不足以分配的时候就会OOM,崩溃,这就是线上崩溃线下无法复现的问题的来源。
分析步骤:
1.当我们看到页面卡顿
比如我们新建一个回调,内部包含static静态变量,然后里面也传入了Context,假设在Activity的OnClick时间内构造它,那么每一次构造都会有Context - XXXActivity对象被保存在这个回调的内部,那么每一次finish都不会释放。
当我们打开AndroidStudio的Memory Profiler的时候我们就可以在Memory里面看到成阶梯状的内存消耗的趋势。这个时候我们通过内存变化曲线(阶梯状)可以判断内存存在泄漏。
我们只需要把我们认为有泄漏的部分,进行堆转储,导出文件即可
(华为手机 eg P40,当我们使用Memory Profiler的时候会闪退,可能是ROM架构的问题)
接下来,将导出文件转换:
hprof-conv /xxxx/memory_leak.hprof /xxxxx/memory_leak_transed.hprof 不执此命令MAT不能处理堆转储文件
1.打开文件
点击Histogram
2.匹配搜索需要的类的名称
我们可以看见有一个Activity存在存在七个对象 这是不合理的
那么来看看都是谁强引用了吧
看见了七个强引用
选择一个对象 去除软引用 只关注强引用 也可以直接看with all references
查看强引用结果的依赖路径
我们可以看见是EventBus中持有了上下文的引用看看源码
销毁的时候写错了,应该改成
@Override
protected void onDestroy() {
super.onDestroy();
if (EventBus.getDefault().isRegistered(this)) {
//取消注册
EventBus.getDefault().unregister(this);
}
}
这样就释放了。虽然只是一个复制粘贴的问题,但是却真实的影响了性能,不会崩溃,在线上是一个很恶心的bug,反馈到研发这里只是偶现。这就是通过内存分析查找问题的方法 MAT+MemoryProfiler
前后对比
可以看见内存得到了释放~~~~~~~~