嵌入式开发经验:嵌入式开发经验:Android系统的内存管理研究系统的内存管理研究
本文将集中分析Android的内存管理,因为Android系统是在Linux系统的基础上发展起来的,所以在介绍Linux基
本的内存管理的基础上对Android的内存管理进行研究。
1Android系统概述
Android基于Linux平台,主要由操作系统、中间件、用户界面和应用软件组成。采用的是软件堆栈的结构,操作系统的底层仅
提供最基本的系统功能。在Android系统中,基本上使用的是标准的Linux2.6内核,但是Google为了让Android更适合移动手持
设备,对Linux内核进行了各种优化和增强。除了Linux的通用代码外,主要包含体系结构和处理器、Android特定的驱动程序
和标准的设备驱动程序3个方面的内容。Android对Linux内核的增强主要包括Alarm(硬件闹钟)、Ashmem(匿名内存共享)、Low
Memory Killer(低内存管理)、Logger(日志管理)等。本文将集中分析Android的内存管理,因为Android系统是在Linux系统的基
础上发展起来的,所以在介绍Linux基本的内存管理的基础上对Android的内存管理进行研究。
2Linux内存管理
在内存管理方面,Linux系统新旧两个版本(2.6之前和之后)之间有很大的不同。由于Android系统是基于Linux2.6.x内核的,本
文主要介绍Linux2.6在内存管理方面的基本内容。
2.1反向映射机制
Linux2.6引入了基于对象的反向映射机制,这种方法为物理页面设置一个用于反向映射的链表,但是链表上的节点并不是引用
了该物理页面的所有页表项,而是相应的虚拟内存区域(vm_area_struct结构)。虚拟内存区域通过内存描述符(mm_struct结构)
找到页全局目录,从而找到相应的页表项。相对于前一种方法来说,用于表示虚拟内存区域的描述符比用于表示页面的描述符
要少得多,所以遍历后边这种反向映射链表所消耗的时间也会少很多。
page结构中与基于对象的反向映射相关的关键字段有两个:_mapcount和mapping。基于对象的反向映射的实现如下:
struct page{
atomic_t_mapcount;
union{
……
struct{
……
struct address_space*mapping;
};
};
字段_mapcount表明共享该物理页面的页表项的数目,该计数器可用于快速检查该页面除所有者之外有多少使用者在使用,初
始值是-1,每增加一个使用者,该计数器加1。
字段mapping用于区分匿名页面和基于文件映射的页面。如果该字段的最低位置被置位,那么该字段包含的是指向anon_vma
结构(用于匿名页面)的指针;否则,该字段包含指向address_space结构的指针(用于基于文件映射的页面)。
2.2Linux页面回收
Linux中页面回收主要通过两种方式触发:一种是由“内存严重不足”事件触发;另一种是由后台进程kswapd触发,该进程周期性
地运行,一旦检测到内存不足,就会触发页面回收操作。这里主要介绍shrink_zone()函数,此函数是Linux操作系统实现页面
回收的最核心的函数之一,它实现了对一个内存区域的页面进行回收的功能。该函数主要做了两件事:
① 将某些页面从active链表移到inactive链表,这是由函数shrink_active_list()实现的;
② 从inactive链表中选定一定数目的页面,将其放到一个临时链表中,这由函数shrink_inactive_list()完成。
该函数最终会调用shrink_page_list()去回收这些页面。
2.3OOMKiller机制
OOM(Out of Memory)是标准Linux内核(kernel)的一种内存管理机制,当系统内存耗尽时,OOM会选择性的杀掉一些进程以求
释放一些内存。
Linux在2.6.36内核中修正了OOMKiller的行为,跟之前的OOMKiller相比,主要体现在3个方面:第一,将物理内存页面的使用
作为基准而不是虚拟地址空间的大小;第二,导出用户策略的控制权;第三,内核有了一个简单而合理的默认策略。