准备:安卓开发环境、AndroidStudio、模拟器(或开启usb调试的真机)
工具:Memory Monitor、MAT
什么是内存泄露
一些对象有着有限的生命周期。当这些对象所要做的事情完成了,我们希望他们会被回收掉。但是如果有一系列对这个对象的引用,那么在我们期待这个对象生命周期结束的时候被收回的时候,它是不会被回收的。它还会占用内存,这就造成了内存泄露。持续累加,内存很快被耗尽,最后产生crash
java回收未引用对象的内存使用模式如下,因此在下面步骤中生成JavaHeap文件之前我们要先GC,排除无关因素影响
Memory Monitor
- Memory Monitor是AndroidStudio自带的内存监控工具,功能:
- 图表实时显示可用/已分配的java内存
- 实时显示垃圾收集(GC)事件
- 启动垃圾回收事件
- 快速测试app卡顿是否跟过多GC事件有关
- 快速测试app crash是否跟内存不足有关
-
内存监控
AndroidStudio导入项目源码运行安装,或者没有源码的时候直接在模拟器运行debug版apk。可以实时监控系统分配的内存(Allocated)和剩余内存(Free)的变化。
-
获取Java Heap文件步骤
step1:点Initate GC,回收没有引用的对象
step2:点DumpJavaHeap,可以看到生成JavaHeap文件
step3:点击侧边栏Captures->选中Heap文件->右键“export to standard .hprof”,保存为标准文件
-
实例
正常的状态:从leak.activity跳转到其他MainActivity后,执行GC=>内存回落
修改代码,在leak.activity代码中引入静态变量,运行->跳转到MainActvity->GC=>内存值没有下降
认为这里发生了内存泄漏,获取当前内存详细状况,点DumpJava Heap,生成.hprof文件。点击AnalyzerTasks->Perform Analysis,可以定位到出问题的activity,右键点击 Jump to source or Go to instance可跳转到有问题的类和activity。点击右侧顶部栏Shallow Size、Retained Size,可按照不同的标准进行排序
参数解析
Shallow Size:堆中所有实例的总大小(不包括其引用)
Retained Size:这个类的所有实例支配的内存(该对象的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和)
结合MAT定位问题
AndroidStudio里,右键将以上生成的.hprof文件导出成standard.hprof
并在MAT中打开文件,自动生成分析结果。一个内存分布图,鼠标移到不同块的时候,左侧会展示该块的属性
重点看Histogram和DominatorTree
-
Histogram直方图(展示内存中的对象及其个数、大小)
可以看到实例在内存中占比最大的是类ImageView
-
DominatorTree(列出最大的对象及其连接依赖的对象)
拓展
LeakCanary
zombie
emmagee
内存测试的应用
用于定位应用crash的时候,可以一边用自动化对界面进行重复操作一边在androidstudio监控内存状况。分析heap文件定位问题
参考链接
Memory Monitor官网介绍