Android性能优化之内存泄漏

发表于:2016-11-25 11:03

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:JohnnyShieh    来源:51Testing软件测试网采编

  每一个Generation的内存区域都有固定的大小,随着新的对象陆续被分配到此区域,当这些对象总的大小快达到这一级别内存区域的阀值时,会触发GC的操作,以便腾出空间来存放其他新的对象。如下图所示:
  通常情况下,GC发生的时候,所有的线程都是会被暂停的。执行GC所占用的时间和它发生在哪一个Generation也有关系,Young Generation中的每次GC操作时间是最短的,Old Generation其次,Permanent Generation最长。执行时间的长短也和当前Generation中的对象数量有关,遍历树结构查找20000个对象比起遍历50个对象自然是要慢很多的。
  为什么通常情况下,GC发生的时候,所有的线程都会被暂停?
  因为每次GC的时候,需要先找到可作为GC Roots的对象,然后以此搜索引用链,这个过程需要在一致性的内存快照中进行。这个“一致性”表示在整个过程中不能出现对象引用关系不断变化的情况,所以需要暂停所有的执行线程。
  限制应用的内存
  为了整个Android系统的内存控制需要,Android系统为每一个应用程序都设置了一个硬性的Dalvik Heap Size最大限制阈值,这个阈值在不同的设备上会因为RAM大小不同而各有差异。如果你的应用占用内存空间已经接近这个阈值,此时再尝试分配内存的话,很容易引起OutOfMemoryError的错误。
  ActivityManager.getMemoryClass()可以用来查询当前应用的Heap Size阈值,这个方法会返回一个整数,表明你的应用的Heap Size阈值是多少Mb(megabates)。
  还有一个用adb命令查询的方法:
  adb shell getprop dalvik.vm.heapgrowthlimit
  3. 检测与定位内存泄漏
  (1)adb命令
  adb shell dumpsys meminfo {package_name}
  (2)Android Studio的Memory Monitor
  (3)LeakCanary
  (4)MAT
  在Android检查内存泄漏,主要搜索Activity、Fragment、View有没有泄漏。
  4. 如何避免内存的总结
  (1) 注意Activity的泄漏
  内部类引用导致Activity泄漏
  具体见 Android中由Handler和内部类引起的内存泄
  Activity Context被间接引用
  对于大部分非必须使用Activity Context的情况(Dialog的Context就必须是Activity Context),我们都可以考虑使用Application Context而不是Activity的Context,这样可以避免不经意的Activity泄露
  (2) 注意静态变量和单例模式
  静态变量是作为GC Roots,在Android其生命周期基本和进程一样长,所以要非常静态变量引用其他生命周期的对象。虽然单例模式简单实用,提供了很多便利性,但是因为单例的生命周期和应用保持一致,使用不合理很容易出现持有对象的泄漏。
  (3) 注意容器中对象泄漏
  有时候,我们为了提高对象的复用性把某些对象放到缓存容器中,可是如果这些对象没有及时从容器中清除,也是有可能导致内存泄漏的。例如,针对2.3的系统,如果把drawable添加到缓存容器,因为drawable与View的强应用,很容易导致activity发生泄漏。而从4.0开始,就不存在这个问题。解决这个问题,需要对2.3系统上的缓存drawable做特殊封装,处理引用解绑的问题,避免泄漏的情况。
  (4) 注意监听器的注销
  (5) …
  (6) 及时关闭Cursor
  在程序中我们经常会进行查询数据库的操作,但时常会存在不小心使用Cursor之后没有及时关闭的情况。这些Cursor的泄露,反复多次出现的话会对内存管理产生很大的负面影响,我们需要谨记对Cursor对象的及时关闭。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号