Android内存泄漏分析
2016-05-16 15:10
288 查看
1、前言
最近在fix 其他需求bug过程中,居然出现了OOM,程序直接挂了。第一反应是内存泄漏了,于是便开始查找原因。2、现象
首先需要确定是不是内存泄漏,Android Studio的Memory监控(Android Monitors-> Memory)可以很好的呈现问题。第一次打开app时,内存占用在20m左右。
连续多次关闭再打开操作,内存占用达到了90m左右,并且点击initiate GC(红色框按钮)无法回收。
由此,基本可以断定程序发生了内存泄漏。
3、内存分析
AS自带内存分析工具Android Studio集成了一个内存分析工具,在GC按钮右边有一个Dump Java Heap按钮,可以生成当前应用的内存快照,并且提供了简单的内存引用分析。
我们可以着重搜索activity,查看下activity的引用分析,因为大部分内存泄漏都是因为activity引用被生命周期较长的对象持有,不能及时销毁导致的。搜索下可以看到,RxJavaActivity发生了内存泄漏,存在25个实例GC无法回收。继续查看引用分析,可以定位到具体泄漏的对象。Android studio自带的这个内存分析工具,有点乱,看的并不是很清晰,功能也没有那么强大,我们希望工具可以自动帮我们分析并定位到具体发生内存泄漏的位置。
MAT-专业的内存分析工具
MAT可以作为Eclipse插件使用,也可以单独使用,使用方法都类似。如果是分析的内存快照文件是Android Studio Dump出来的,还需要进行一次转换,不然MAT无法识别。转换工具,Android SDK中已经有了,具体位置:sdk路径/platform-tools/hprof-conv。转换命令:hprof-conv input.hprof out.hprof。如果是使用MAT Dump下来的内存快照,就不需要转换了。
使用MAT打开快照文件,选择Leak Suspects Report。然后打开Histogram,可以展示出快照中所有内存实例对象列表。
在Histigram中可以使用正则筛选出希望查看的内存对象,例如查看RxJavaActivity。结果和使用AS工具分析的基本一致。
右键,可以直接查看Paths to GC Roots,并且可以排除掉弱引用,软引用等内存不足时,系统可以回收掉的引用。
结果呈现比AS更加清晰,可以清楚的看到哪些对象持有了RxJavaActivity引用,导致内存泄漏,并且很容易定位到具体代码。
例如,这里的例子中可以判断出是我们在退出RxJavaActivity时,没有及时取消Subscription订阅,mSubscription对象仍然持有了RxJavaActivity的引用,最终导致RxJavaActivity不能销毁,形成了内存泄漏。
LeakCanary
LeakCanary是Square公司出品的自动监控内存泄漏的library。在Android中使用非常方便,两步操作。
build.gradle添加Gradle依赖,可以指定在debug时才监控,release版本不监控
dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3' }
Application中调用install即可。
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); LeakCanary.install(this); } }
经过上述两个步骤,app已经具有了自动内存监控功能,并且当发生内存泄漏时,可以自动发出通知。
项目测试截图:
相关文章推荐
- c语言内存泄露示例解析
- 解决js函数闭包内存泄露问题的办法
- IE下使用jQuery重置iframe地址时内存泄露问题解决办法
- Android App调试内存泄露之Cursor篇
- js内存泄露的几种情况详细探讨
- Javascript 闭包引起的IE内存泄露分析
- JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
- 深入解析PHP垃圾回收机制对内存泄露的处理
- PHP脚本内存泄露导致Apache频繁宕机解决方法
- 容易造成JavaScript内存泄露几个方面
- 关于js内存泄露的一个好例子
- 总结JavaScript在IE9之前版本中内存泄露问题
- Android垃圾回收机制解决内存泄露问题
- Android编程中避免内存泄露的方法总结
- C语言中的内存泄露 怎样避免与检测
- PHP CURL 内存泄露问题解决方法
- Java中典型的内存泄露问题和解决方法
- Android中Handler引起的内存泄露问题解决办法
- 浅谈Java编程中的内存泄露情况
- 理解Java中的内存泄露及解决方法示例