使用android studio检测app内存泄漏【转载】
Android开发中难免会遇到各种内存泄漏,如果不及时发现处理,会导致出现内存越用越大,可能会因为内存泄漏导致出现各种奇怪的crash,甚至可能出现因内存不足而导致APP崩溃。
一般检测android内存泄漏都是使用android studio自带的Monitor工具结合mat,或者是使用第三方开源库工具:leakCanary.
但是这两者都不是十分完美的方式:
Monitor工具结合mat有如下的问题:
- 不保存过去的数据,如果需要几个小时乃至几天的数据,这个工具就做不到;
- 有些内存泄露很慢,可能需要累计几天才有明显的增长,用自带的工具就不容易发现;
leakCanary有如下的问题:
- 工具比较死板,有些程序逻辑错误并不能检测出来.
- 另外有些内存可以优化的地方,使用leakcanary也是分析不出来的,比如程序中用到集合类,如果用完不调用clear并置为null的话,导致一个游离的对象集合会在内存中存在一段时间,只有等到下次GC检测到对象没有用的时候才会回收。
内存泄漏分析工具
Android的内存泄漏分析工具常用有Android Studio和基于eclipse的MAT(Memory Analyzer Tool)。通过两者配合,可以发挥出奇妙的效果。Android Studio能够快速定位内存泄漏的Activity,MAT能根据已知的Activity快速找出内存泄漏的根源。
第一步:强制GC,生成Java Heap文件
我们都知道Java有一个非常强大的垃圾回收机制,会帮我回收无引用的对象,这些无引用的对象不在我们内存泄漏分析的范畴,Android Studio有一个Android Monitors帮助我们进行强制GC,获取Java Heap文件。
强制GC:点击
Initate GC(1)按钮,建议点击后等待几秒后再次点击,尝试多次,让GC更加充分。然后点击Dump Java Heap(2)按钮,然后等到一段时间,生成有点慢。

生成的Java Heap文件会在新建窗口打开。

第二步:分析内存泄漏的Activity
点击Analyzer Tasks的Perform Analysis(1)按钮,然后等待几秒十几秒不等,即可找出内存泄漏的Activity(2)。

那么我们就可以知道内存泄漏的Activity,因为这个例子比较简单,其实在(3)就已经可以看到问题所在,如果比较复杂的问题Android Studio并不够直观,不够MAT方便,如果Android Studio无法解决我们的问题,就建议使用MAT来分析,所以下一步我们就生成标准的hprof文件,通过MAT来找出泄漏的根源。
第三步:转换成标准的hprof文件
刚才生成的Heap文件不是标准的Java Heap,所以MAT无法打开,我们需要转换成标准的Java Heap文件,这个工具Android Studio就有提供,叫做Captures,右击选中的hprof,Export to standard .hprof选择保存的位置,即可生成一个标准的hprof文件。

第四步:MAT打开hprof文件
MAT的下载地址,使用方式和eclipse一样,这里就不多说了,打开刚才生成的hprof文件。点击(1)按钮打开Histogram。(2)这里是支持正则表达式,我们直接输入Activity名称,点击enter键即可。

搜索到了目标的Activity

右击搜索出来的类名,选择
Merge Shortest Paths to GC Roots的exclude all phantom/weak/soft etc. references,来到这一步,就可以看到内存泄漏的原因,我们就需要根据内存泄漏的信息集合我们的代码去分析原因。

第六步:根据内存泄漏信息和代码分析原因
使用Handler案例分析,给出的信息是Thread和android.os.Message,这个Thread和Message配合通常是在Handler使用,结合代码,所以我猜测是Handler导致内存泄漏问题,查看代码,直接就在函数中定义了一个final的Handler用来定时任务,在Activity的onDestroy后,这个Handler还在不断地工作,导致Activity无法正常回收。
// 导致内存泄漏的代码protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);textView = (TextView) findViewById(R.id.text);final Handler handler = new Handler();handler.post(new Runnable() { @Override public void run() { textView.setText(String.valueOf(timer++)); handler.postDelayed(this, 1000); } });}
修改代码,避免内存泄漏
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);textView = (TextView) findViewById(R.id.text);handler.post(new Runnable() { @Override public void run() { textView.setText(String.valueOf(timer++)); if (handler != null) { handler.postDelayed(this, 1000); } }});}private Handler handler = new Handler();@Overrideprotected void onDestroy() { super.onDestroy(); // 避免Handler导致内存泄漏 handler.removeCallbacksAndMessages(null); handler = null;}
重新测试,确保问题已经解决。
使用android studio检测app内存泄漏【转载】的更多相关文章
- Android Studio +MAT 分析内存泄漏实战
对于内存泄漏,在Android中如果不注意的话,还是很容易出现的,尤其是在Activity中,比较容易出现,下面我就说下自己是如何查找内存泄露的. 首先什么是内存泄漏? 内存泄漏就是一些已经不使用的对 ...
- 使用 Android Studio 检测内存泄漏与解决内存泄漏问题
本文在腾讯技术推文上 修改 发布. http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BF ...
- Android 性能优化之内存泄漏检测以及内存优化(中)
https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...
- 使用新版Android Studio检测内存泄露和性能
内存泄露,是Android开发者最头疼的事.可能一处小小的内存泄露,都可能是毁于千里之堤的蚁穴. 怎么才能检测内存泄露呢?网上教程非常多,不过很多都是使用Eclipse检测的, 其实1.3版本以后的 ...
- monkey测试===通过monkey测试检查app内存泄漏和cpu占用
最近一直在研究monkey测试.网上资料很多,但都是一个抄一个的.原创的很少 我把检查app内存泄漏的情况梳理一下: 参考资料: Monkey测试策略:https://testerhome.com/t ...
- [转]Android 如何有效的解决内存泄漏的问题
Android 如何有效的解决内存泄漏的问题 前言:最近在研究Handler的知识,其中涉及到一个问题,如何避免Handler带来的内存溢出问题.在网上找了很多资料,有很多都是互相抄的,没有实际的 ...
- 老李分享:Android性能优化之内存泄漏1
老李分享:Android性能优化之内存泄漏 前言 对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我 ...
- 【Android Studio安装部署系列】十八、Android studio更换APP应用图标
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio新建项目后会有一个默认图标,那么如何更换图标呢? 替换图标 这个方案不建议直接在已有项目上更换图标,建议 ...
- Android开发 |常见的内存泄漏问题及解决办法
在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...
随机推荐
- Modbus Com SerialPort
项目中用到的工具,串口modbus协议读写数据. public class ModbusHelper { private readonly SerialPort _serialPort; privat ...
- js常用字符处理方法
JS自带函数concat将两个或多个字符的文本组合起来,返回一个新的字符串.var a = "hello";var b = ",world";var c = a ...
- 从CentOS官网下载系统镜像详细教程
很多新手小白鼠想学习CentOS系统,但是不知道镜像去哪里搞,随便去个第三方发现要么要注册,要么各种广告病毒,或者好不容易找到官网,点进去一看却一脸懵逼,不仅全英文,有些专业术语也不懂啊,不要担心 ...
- 11、Map、可变参数、Collections
Map接口 Map集合概述 *A:Map集合概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同 a:Collection中的集合,元素 ...
- POJ 1006 Biorhythms --中国剩余定理(互质的)
Biorhythms Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 103539 Accepted: 32012 Des ...
- SqlServer示例数据库Northwind(一)——实体关系
在学习Spss统计分析.EA画实体关系图.PowerDesigner画数据库模型图等时,苦于找不到一个好的实例.由于实际工作中项目使用的表结构属于公司的商业保密内容,且在和大家交流时,其结构大家也不熟 ...
- Freebsd10.3(FreeBSD11 Beta1)使用手记
Freebsd10.3(FreeBSD11 Beta1)使用手记 1.安装系统. 2.设置ssh2登录,并开启ftp. (1)编辑/etc/ssh/sshd_config文件,设置如下: Permit ...
- 51NOD1847:奇怪的数学题
传送门 Sol 设 \(f(d)\) 表示 \(d\) 所有约数中第二大的,\(low_d\) 表示 \(d\) 的最小质因子 \[f(d)=\frac{d}{low_d}\] 那么 \[\sum_{ ...
- c# 圆上坐标点
var x=-33204.0924438; //圆心x var y=-9512.41208658; //圆心y var r=1000;//半径 var angle=30;//角度 var tmpX ...
- Node.js 常用 API
Node.js v6.11.2 Documentation(官方文档) Buffer Prior to the introduction of TypedArray in ECMAScript 20 ...