Android 中的内存管理

在介绍 Fresco 内存管理之前,有必要先简单了解下 Android 中的内存管理机制。

前面的文章中有介绍到,在 Android 中,每一个应用程序会分配一个单独的 Linux 用户进程,而每一个进程都会单独使用一个 Dalvik 虚拟机实例来运行,这样做的目的是:

  • 应用之间是相互独立的,一旦某个应用崩溃了,仅仅是这个应用的进程被销毁,系统中的其他应用不会受到影响
  • 系统会为不同类型的进程分配不同的内存使用上限,如果某个应用使用的内存超过了这个上限值,则会引发 OOM

在 Android 中,一个应用程序在运行的时会分配一个内存区,内存区分为栈内存和堆内存

  • 栈(Stack):线程私有(内存区只能被当前线程使用),生命周期与线程相同,由虚拟机控制,主要用于存储局部变量,操作数,方法出口等信息,以帧为单位入栈出栈(一个方法从调用至执行完成的过程,就对应一个帧在栈中的入栈出栈过程,关于栈帧的概念,可以参考 这篇文章
  • 堆(Heap):在 Android 中,堆分为 Dalvik vm Heap 和 Native Heap,两者是相互独立的,前者是 java 进程所使用的内存区,是开发中常用到的堆区,也是垃圾回收器( GC )管理的主要区域,后者是 native 进程所使用的内存区,通常在 NDK 开发中用到:

    • Dalvik vm Heap:线程共享(内存区被当前进程中的所有线程共享,在应用启动时创建),由程序控制,用于分配 java 对象,代码中 new 创建的对象都在这个内存区中,内存大小有限制,其最大值是前面文章中提到过的一个应用程序可以使用的最大内存值,如果使用的内存超出这个值,便会引发 OOM

    • Native Heap:native 进程的内存区,用于分配 C/C++ 代码中 malloc 申请的内存,内存大小不受单个进程可分配内存的限制,但是受系统限制

通过以上描述,可以总结一下:Android 中一个应用程序是运行在一个单独的 Dalvik 虚拟机创建的进程中,虚拟机的内存结构中有两个重要的内存区,栈和堆,其中栈主要用来存放局部变量和方法等,而堆主要是用来存放对象,并且有垃圾回收机制,但是堆的内存大小是有限制的,内存使用超出后便会引发 OOM;在 NDK 开发中,会有一个 Native Heap,这个内存区域主要是用来存放 C/C++ 代码申请的空间,内存大小没有限制,没有垃圾回收机制,因此不会引发 OOM,但是需要手动释放内存

Android 中的 Bitmap

Android 中图片存在的主要形式是位图(Bitmap),也就是由像素点组成的图像,每个点可以由多种色彩表示,包括2、4、8、16、24和32位色彩。位图通常需要占用大量的内存,并且是在 Dalvik vm Heap 中分配内存的,因此很容易引起 GC, 频繁的 GC 可能导致运行卡顿。

Fresco 中的缓存管理

根据官方文档的描述,在 Fresco 中使用了三级缓存,分别是:

  • Bitmap 缓存:存储 Bitmap 对象,这些 Bitmap 对象可以立刻用来显示或者用于后处理。在 5.0 以下系统,Bitmap 缓存位于 ashmem(类似 Native Heap,具体可以参考 这篇文章),这样 Bitmap 对象的创建和释放将不会引发 GC,更少的 GC 会使应用运行得更加流畅。5.0 及其以上系统,内存管理有了很大改进,所以Bitmap缓存直接位于 Dalvik vm Heap 上。当应用在后台运行时,该缓存会被清空。

  • 内存缓存:这个缓存存储的是原始压缩格式的图片。从该缓存取到的图片在使用之前,需要先进行解码。如果有调整大小,旋转,或者 WebP 编码转换工作需要完成,这些工作会在解码之前进行。应用在后台时,这个缓存同样会被清空。

  • 文件缓存:和未解码的内存缓存相似,文件缓存存储的是未解码的原始压缩格式的图片,在使用之前同样需要经过解码等处理。和内存缓存不一样,应用在后台时,内容是不会被清空的。即使关机也不会。用户可以随时用系统的设置菜单中进行清空缓存操作

Image Pipeline

在 Fresco 中,Image Pipeline 负责完成图像加载,大致流程如下:

  1. 检查内存缓存,如有,返回
  2. 后台线程开始后续工作
  3. 检查是否在未解码内存缓存中。如有,解码,变换,返回,然后缓存到内存缓存中。
  4. 检查是否在文件缓存中,如果有,变换,返回。缓存到未解码缓存和内存缓存中。
  5. 从网络或者本地加载。加载完成后,解码,变换,返回。存到各个缓存中。

下面是官方给出的一张图片用于描述 Image Pipeline

上面的步骤描述了图片的加载过程,关于 Fresco 中更详细的内存管理,可以参考 这片文章

Comments

    1. 谭岑谭岑 Article Author

      简单点说,就是虚拟机中方法调用和执行的数据结构,这个涉及到虚拟机的运行机制,不是本文的重点,所以就简单带过

发表评论

电子邮件地址不会被公开。 必填项已用*标注