ART和Dalvik虚拟机都使用分页和内存映射来管理内存。应用修改的任何内存,无论修改的方式是分配新对象还是轻触内存映射的页面,都会一直驻留在 RAM 中,并且无法换出。

要从应用中释放内存,只能释放应用保留的对象引用,使内存可供垃圾回收器回收。

垃圾回收

Android 的内存堆是分代的,这意味着它会根据分配对象的预期寿命和大小跟踪不同的分配存储分区。

堆的每一代对相应对象可占用的内存量都有其自身的专用上限。每当一代开始填满时,系统便会执行垃圾回收事件以释放内存。垃圾回收的持续时间取决于它回收的是哪一代对象以及每一代有多少个活动对象。

共享内存

每个应用进程都从一个名为 Zygote 的现有进程分叉。系统启动并加载通用框架代码和资源(如 Activity 主题背景)时,Zygote 进程随之启动。为启动新的应用进程,系统会分叉 Zygote 进程,然后在新进程中加载并运行应用代码。

Android 的内存类型

Android 设备包含三种不同类型的内存:RAM、zRAM 和存储器。

Android内存

RAM 是最快的内存类型,但其大小通常有限。

zRAM 是用于交换空间的 RAM 分区。所有数据在放入 zRAM 时都会进行压缩,然后在从 zRAM 向外复制时进行解压缩。这部分 RAM 会随着页面进出 zRAM 而增大或缩小。设备制造商可以设置 zRAM 大小上限。

存储器中包含所有持久性数据(例如文件系统等),以及为所有应用、库和平台添加的对象代码。存储器比另外两种内存的容量大得多。在 Android 上,存储器不像在其他 Linux 实现上那样用于交换空间,因为频繁写入会导致这种内存出现损坏,并缩短存储媒介的使用寿命。

内存分页

RAM的每个页面大小为4KB。系统将页面视为“可用”或“未使用”。

已使用页面为当前正在使用的内存页,分为以下类别:

缓存页(Cached)

有存储器中的文件(例如代码或内存映射文件)支持的内存

私有页(Private):由一个进程拥有且未共享

干净页:存储器中未经修改的文件副本,可由 kswapd(内核交换守护进程)删除以增加可用内存

脏页:存储器中经过修改的文件副本;可由 kswapd 移动到 zRAM 或在 zRAM 中进行压缩以增加可用内存

共享页(Shared)

匿名页(Anonymous)

没有存储器中的文件支持的内存

脏页(Dirty):可由 kswapd 移动到 zRAM/在 zRAM 中进行压缩以增加可用内存

内存不足管理

内存交换守护进程(kswapd)

内核交换守护进程 (kswapd) 是 Linux 内核的一部分,用于将已使用内存转换为可用内存。

当设备上的可用内存不足时,该守护进程将变为活动状态。

Linux 内核设有可用内存上下限阈值。

当可用内存降至下限阈值以下时,kswapd 开始回收内存。当可用内存达到上限阈值时,kswapd 停止回收内存。

待续