1 简述
内存泄漏也就是本该被GC回收掉的东西由于某种原因没有被回收掉,从而长期存留在内存中无法被回收,这就是内存泄漏
2 什么原因引起的内存泄漏
- 内部类隐形的持有外部类的引用导致内存泄漏
- 静态变量导致内存泄漏
- 错误的使用Activity Context
- 资源对象没关闭造成的内存泄漏
- 集合中对象没清理造成的内存泄漏
3使用android studio判断产生泄漏
1.底部功能卡片切换到android monitor,选择Monitors
1.png
左上角依次是:
- Enabled 监控的开关
- initiate GC 手动触发GC
- Dump java Heap 导出内存信息
- start Allocation Tracking 追踪内存分配
2.反复操作app,观察内存是否增加,退回到首页之后内存没有降低回最初水平(观察钱需要点击 initiate GC,防止非泄漏的内存没有被及时释放,误认为泄漏)
4导出hprof文件
1.点击Dump java Heap 生成对应的hprof文件
2.hprof文件转换
生成的hprof文件需要转换成标准的hprof文件才能使用MAT,所以需要转换一下。转换方法有两种:
1)在侧边栏中打开Captures文件,选中文件点击右键,export出标准的hprof文件
2)打开命令行工具 切换到 androidSDK\tools所在目录,输入命令 hprof-conv xxx.hprof yyy.hprof
5使用MAT查看具体泄漏
打开MAT, file -> open heap Dump 引入 hprof文件
2.png
3.png
上图中第一个红色区域为柱状图查看,点击之后出现如上图中histogram 列表,然后点击第二个红色区域,选择group by package,得到如下该图,按照报名分类可以将自身代码于系统源码区分开来,容易查找app中的内存泄漏问题。
3.png
选择要查看的对象,右键->Merge Shortest Paths To GC Roots-> exclude all phantom/weak/soft etc.references
4.png
最终获得如下引用路径图
5.png
目测是BaseEventPublisher中持有了DriverBar的引用,根据实际代码分析为onremove方法中没有调用super.onRemove方法,导致基类onadd中注册的监听没有被取消