Android内存优化及内存回收

Android内存优化及内存回收

Android 内存回收

1. 内存回收算法 (引用计数法,标注清理,拷贝,逐代回收)
  • 引用计数法原理实际上是生成对象的时候在该对象的对象头中分配一个空间用来保存该对象被引用的次数,如果该对象被引用,引用次数+1,如果删除该对象的引用,引用次数就-1,当引用次数为0时,就会回收该对象。

  • 标注清理 就是当系统内存不足的时候系统就当暂停当前所有的线程,从GC Root 开始将整个内存遍历一遍,保留所有可以被GC Root 直接或间接引用到的对象,而剩下未被引用的对象就会被当做垃圾回收

  • 拷贝 就是当内存空间均分为两部分,每次只使用其中的一块空间,当被使用的那部分空间不足时触发GC,GC将当前空间里的所有活动的对象复制到另一块空间中,把原来空间中的所有对象都回收。

  • 逐代回收 就是将内存划分为不同的区域,根据对象的生命同期存放于不同的区域,生命周期短的区域采用拷贝算法进行对象回收,而生命周期长的区域则采用标注清理或标注整理的方式进行垃圾回收。

2. Android 内存回收等级

Android 应用退出的时候,并不清理其所占用的内存,Linux内核进程也相应的继续存在,所谓”退出并但并不关闭”,从而使用户调用程序时候能第一时间得到响应。当系统内存不足时,系统将激活内存回收过程,为了不因内存回收影响用户体验,Android 基于进程中运行的组件及其状态规定了五个回收优先级:

  • IMPORTANCE_FOREGROUND(前台) 前台进程就是目前正在屏幕上显示的进程和一些系统进程,即用户可见,并能与之交互的进程。
  • IMPORTANCE_VISIBLE(可见) 可见进程是指部分页面能被用户看见,却不在前台与用户交互的进程。
  • IMPORTANCE_SERVICE(服务) 服务进程是指通过startService方法启动的进程,例如后台播放音乐或后台下载进程
  • IMPORTANCE_BACKGROUND(后台) 后台进程是指对用户不可见的进程。
  • IMPORTANCE_EMPTY(空) 空进程是指该进程内部没有任何东西在运行。

五个等级的回收优先级为:
空进程,后台进程,服务进程,可见进程,前台进程

3. Android 触发内存回收条件
  • 当堆内存增长到一定程度时会触发,此时触发可以对堆内存中没有用的对象进行回收。
  • 当应用程序调用System.gc()方法时触发。
  • 当堆内存已满,系统需要更多的内存时触发。
  • 当创建一个内存分析文件HPROF时触发
  • 应用程序准备抛出OOM异常之前进行最后的努力而触发GC

    Android 内存优化

    1. UI优化
  • 布局重用 提高了布局的重用性。
  • 减少视图的层级 删除多余的布局层级
  • 使用 是一个不可见,大小为0的View,主要用来实现View的延时加载,避免浪费资源,在需要的时候才加载的View.
2. 代码优化
  • 避免创建不必要的对象,避免创建短命的临时对象.
  • 静态方法代替虚拟方法,如果不需要访问某对象的字段,将方法设置为静态,调用会加速15%到20%。
  • 避免内部Getters/Setters
  • 访问成员变量比访问本地变量慢得多
  • 永远不要在for的第二个条件中调用任何方法。
  • 复杂算法尽量用C完成
  • 减少不必要的全局变量
  • 缓存,适量使用缓存,不要过量使用,因为内存有限,能保存路径地址的就不要存放图片数据,不经常使用的尽量不要缓存,不用时就清空。
  • 关闭资源对象,对Sqlite,Curse,文件,I/O操作都应该要关闭。
  • 对大型的图片进行缩放之后,过时的Bitmap对象一定要及时回收,并将此对象置空
  • 构造Adapter时使用缓存converView.
  • 动态注册广播之后 一定要注销广播。