Android内存泄漏检测
一、背景
内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。通常我们开发的app如果没有检测内存泄漏严重时会导致崩溃,所以还是有必要检测一下的。
二、android mat工具使用
1、 mat(Memory Analyzer Tool)下载地址:
/mat/downloads.php
2、 安装
安装很简单,把下载的zip包解压到一个地方,进入该目录,点击MemoryAnalyzer.exe就能启动了,不过前提是你已经安装好了JAVA环境才行
3、 使用
1) 生成hprof文件,这个文件就是你dump的内存数据,这里介绍一下android studio如何生成hprof文件:
a)打开android profile,找到下图红框处的图标,点击后就会开始dump内存
b)Dump内存结束后会出现下图,选择红框处点击就会生成hprof文件,将这个文件保存在某个路径下
c)将生成的hprof文件进行转换,转换后才能用于mat工具,找到保存的hprof文件,执行命令hprof-conv input.hprof out.hprof,其中hprof-conv是在sdk目录下的plateform-tools下面,最后将转换后的文件导入mat工具里分析
2) 分析内存泄漏
a)点击下图红框处的Histogram,然后会出现所有的对象列表
b)在类名搜索里面搜索Activity,特别注意搜索是区分大小写的,如果输入activity,是搜不到任何Activity的
c)在选中的Activity右击选择list objects,其中
list objects -- with outgoing references : 查看这个对象持有的外部对象引用。
list objects -- with incoming references : 查看这个对象被哪些外部对象引用。
这里我们是查看Activity被哪些对象持有导致没有被释放,所以选择with incoming references
d)在选中的Activity右击Path To GC Roots,目的是为了找出Activity没有被回收的罪魁祸首
e) 查找内存泄漏的最终原因
如上图,我们发现MainActivity被三个对象持有,其中后两个是系统对象,这里就不用管了,我们重点看第一个,可以看到第一个最终延伸到一个dialog对象,这边我们先看一下测试源码:
public class MainActivity extends AppCompatActivity{ private static Dialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dialog = new Dialog(this,R.style.AppTheme);dialog.show();dialog.dismiss();}}
可以看到我们做了一个简单的内存泄漏实验,一个静态的Dialog对象持有Activity对象,因为是静态的,所以退出app后还是存在的,因此Activity无法被释放,然后结合我们的内存分析可以看到我们找到了这个罪魁祸首。
shallow heap -- 对象本身大小
retained heap -- 对象被回收后会释放的大小