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来回收。

最新文章

  1. 使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句
  2. HttpRequest重写,解决资源战胜/链接超时/分块下载事件通知 问题。
  3. HDU 4647 Another Graph Game(贪心)
  4. javascript正则表达式介绍
  5. Eclipse反编译插件jad安装
  6. 网络-数据包在路由转发过程中MAC地址和IP地址,变与不变
  7. 【一】php 操作符
  8. Java数据类型简单认识
  9. Java Concurrency - 浅析 CountDownLatch 的用法
  10. 了解下SoftReference
  11. 山东省2016acm省赛
  12. Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路
  13. hdu 2546 饭卡(DP)
  14. c# 交换两个变量
  15. Linux Socket编程注意事项
  16. [置顶] 纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!
  17. JAVA设计模式:模板设计模式
  18. 洛谷 P1019 单词接龙【经典DFS,温习搜索】
  19. Long转Date/页面自定义标签
  20. eShopOnContainers 知多少[9]:Ocelot gateways

热门文章

  1. PAT天梯赛L1-020 帅到没朋友
  2. Mybatis学习笔记(八) —— Mybatis整合spring
  3. redis修改密码和更改端口
  4. C语言单片机中延时程序的实现
  5. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_CLR
  6. Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot(二分或者尺取)
  7. POJ2886Who Gets the Most Candies?(线段树之约瑟夫)
  8. tomcat+nginx+memcache
  9. Go语言基础之9--指针类型详解
  10. Day3监督学习——决策树原理