Android - 看似内存泄漏,实则不是,记一次内存泄漏的案例分析
APP中常常会存在内存泄漏的问题,一个简单的测试方法是,多次进入和退出同一页面(Activity),使用adb shell中的dumpsys meminfo com.android.settings | grep "Activities"来查看Activity的数量(以com.android.settings为例)。
如果随着多次进入和退出,Activity的数量一致在增长,没有下降,那么便很大有可能是内存泄漏的问题。当然有可能是GC还没有回收的缘故,如果再显示地对调用GC回收(DDMS工具的Cause GC按钮),如果Acitivity的数量仍然没有降低,那么概率就更大了。需要从代码层面进一步分析。
今天遇到的例子就是,通过上述方法,看似遇到了内存泄漏,其实不是。
关键点:通过MAT工具和代码分析,未回收的对象被system_process进程引用,显示调用system_process GC即可解决问题,不属于内存泄漏。
案例简介:在原生Android Open Source Project的Settings APP代码中,有一个Fragment类叫AccountPreferenceBase,运行在进程com.android.settings中,通过以上方法,发现这个类可能存在内存泄漏,于是在重现问题后,借助MAT工具,来分析,得到与此对象相关的引用链如下:
由上图可知未被GC回收的AccountPreferenceBase与ContentResolver有关。通过代码分析,在AccountPreferenceBase中,相关的代码是如下,
进一步分析,在onResume时,调用addStatusChangeListener时,内部会调用RemoteCallbackList的register方法(将callback的binder对象push进一个ArrayMap)。如果不再页面退出时,及时从ArrayMap中delete掉此binder对象,就会有内存泄漏的问题。但是我们在onPause中发现,其实已经调用了removeStatusChangeListener,其内部就会调用unregister方法,从ArrayMap中delete掉正确的binder对象。所以代码的写法没有问题。
那是什么原因导致GC没有回收我们的Activity呢?
原因就是,此ArrayMap是在system_process进程中,并非在com.android.settings的进程中,delete之后,如果执行一次GC(或者我们显示地对system_process调用一次GC),那么对象就会被回收。引用的settings进程中的Activity也会被回收释放。
所以在此案例中,内存泄漏不存在。
因此在遇到内存泄露的情况时,还是需要根据代码来具体分析,GC回收的时机不确定,可通过显示地调用GC来回收对象,排除某些内存泄露的可能。当然跨进程时,要调用正确进程的GC来回收。
最新文章
- 使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句
- HttpRequest重写,解决资源战胜/链接超时/分块下载事件通知 问题。
- HDU 4647 Another Graph Game(贪心)
- javascript正则表达式介绍
- Eclipse反编译插件jad安装
- 网络-数据包在路由转发过程中MAC地址和IP地址,变与不变
- 【一】php 操作符
- Java数据类型简单认识
- Java Concurrency - 浅析 CountDownLatch 的用法
- 了解下SoftReference
- 山东省2016acm省赛
- Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路
- hdu 2546 饭卡(DP)
- c# 交换两个变量
- Linux Socket编程注意事项
- [置顶] 纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!
- JAVA设计模式:模板设计模式
- 洛谷 P1019 单词接龙【经典DFS,温习搜索】
- Long转Date/页面自定义标签
- eShopOnContainers 知多少[9]:Ocelot gateways
热门文章
- PAT天梯赛L1-020 帅到没朋友
- Mybatis学习笔记(八) —— Mybatis整合spring
- redis修改密码和更改端口
- C语言单片机中延时程序的实现
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_CLR
- Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot(二分或者尺取)
- POJ2886Who Gets the Most Candies?(线段树之约瑟夫)
- tomcat+nginx+memcache
- Go语言基础之9--指针类型详解
- Day3监督学习——决策树原理