首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

Android 操作系统的内存储器回收机制

2013-10-09 
Android 操作系统的内存回收机制Android 是一款基于 Linux 内核,面向移动终端的操作系统。为适应其作为移动

Android 操作系统的内存回收机制

Android 是一款基于 Linux 内核,面向移动终端的操作系统。为适应其作为移动平台操作系统的特殊需要,谷歌对其做了特别的设计与优化,使应用程序关闭但不退出,并由操作系统进行进程 的回收管理。本文在 Application Framework 与 Linux 内核两个层次上,以进程为粒度,对 Android 操作系统的进程资源回收机制进行了剖析。读者可以从本文获得对 Android 应用程序的生存周期的进一步理解,从而更加合理、高效地构建应用程序。

Android APP 的运行环境

Android 是一款基于 Linux 内核,面向移动终端的操作系统。为适应其作为移动平台操作系统的特殊需要,谷歌对其做了特别的设计与优化,使得其进程调度与资源管理与其他平台的 Linux 有明显的区别。主要包含下面几个层次:

    Application Framework

    Application Framework 将整个操作系统分隔成两个部分。对应用开发者而言,所有 APP 都是运行在 Application Framework 之上,而并不需要关心系统底层的情况。Application Framework 层为应用开发者提供了丰富的应用编程接口,如 Activity Manager,Content Provider,Notification Manager,以及各种窗口 Widget 资源等。在 Application Framework 层,Activity 是一个 APP 最基本的组成部分。一般每个 Activity 对应于屏幕上的一个视图(或者说一屏),一个 APP 可以有一个或者多个 Activity。应用程序被打包成 .apk 格式的文件,由 Dalvik VM 解释执行。

    Dalvik VM

    Dalvik 虚拟机采用寄存器架构,而不是 JVM 的栈结构。Java 程序编译后的 .class 文件并不能在 Dalvik 中解释执行。因此 Google 提供了一个 dx 工具,用于将 .class 文件转换成 Dalivk 能够识别的 .dex 格式。具体 Dalvik VM 的细节不是本文重点,以下不再讨论。

    Linux kernel

    由上所述,所有的 APP 都是由 Java 代码编写并在 Dalvik VM 中得到解释执行。在 Android 操作系统中,每个 Dalvik VM 的每个 Instance 都对应于 Linux 内核中的一个进程。可以使用 adb shell 工具查看系统中的当前进程。如下图所示,Android2.3.3 启动后内核中的进程列表。



    图 1. Android 2.3 中的进程列表(部分)
    Android 操作系统的内存储器回收机制

    图 1 中,UID 标识为 app_xx 的每一项都是一个 app 所占用的进程,可见 Android 设计使得每个应用程序由一个独立的 Dalvik 实例解释执行,而每个 Linux 内核进程加载一个 Dalvik 实例,通过这种方式提供 app 的运行环境。如此,每个 APP 的资源被完全屏蔽,互不干扰。虽然同时引入了进程间通信的困难,但也带来了更强的安全性。

Android 内存回收原则

下面将从 Application Framework 和 Linux kernel 两个层次分析 Android 操作系统的资源管理机制。

Android 之所以采用特殊的资源管理机制,原因在于其设计之初就是面向移动终端,所有可用的内存仅限于系统 RAM,必须针对这种限制设计相应的优化方案。当 Android 应用程序退出时,并不清理其所占用的内存,Linux 内核进程也相应的继续存在,所谓“退出但不关闭”。从而使得用户调用程序时能够在第一时间得到响应。当系统内存不足时,系统将激活内存回收过程。为了不因 内存回收影响用户体验(如杀死当前的活动进程),Android 基于进程中运行的组件及其状态规定了默认的五个回收优先级:

IMPORTANCE_FOREGROUND:

IMPORTANCE_VISIBLE:

IMPORTANCE_SERVICE:

IMPORTANCE_BACKGROUND:

IMPORTANCE_EMPTY:

这几种优先级的回收顺序是 Empty process、Background process、Service process、Visible process、Foreground process。关于划分原则参见http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html文件中。

ActivityManagerService 集中管理所有进程的内存资源分配。所有进程需要申请或释放内存之前必须调用 ActivityManagerService 对象,获得其“许可”之后才能进行下一步操作,或者 ActivityManagerService 将直接“代劳”。类 ActivityManagerService 中涉及到内存回收的几个重要的成员方法如 下:trimApplications(),updateOomAdjLocked(),activityIdleInternal() 。这几个成员方法主要负责 Android 默认的内存回收机制,若 Linux 内核中的内存回收机制没有被禁用,则跳过默认回收。

默认回收过程

Android 操作系统中的内存回收可分为两个层次,即默认内存回收与内核级内存回收,本章重点对默认内存回收机制进行研究,Linux 内核层次的内存回收机制将在下一张介绍。 本章所有代码可参见 ActivityManagerService.java。

回收动作入口:activityIdleInternal()

Android 系统中内存回收的触发点大致可分为三种情况。第一,用户程序调用 StartActivity(), 使当前活动的 Activity 被覆盖;第二,用户按 back 键,退出当前应用程序;第三,启动一个新的应用程序。这些能够触发内存回收的事件最终调用的函数接口就是 activityIdleInternal()。当 ActivityManagerService 接收到异步消息 IDLE_TIMEOUT_MSG 或者 IDLE_NOW_MSG 时,activityIdleInternal() 将会被调用。代码如下:


清单 1. IDLE_NOW_MSG 的处理方式

 static struct task_struct *select_bad_process(unsigned long *ppoints,                                             struct mem_cgroup *mem)  {         for_each_process(p) {                points = badness(p, uptime.tv_sec);                if (points > *ppoints || !chosen) {                        chosen = p;                        *ppoints = points;                }         }         return chosen;  } 

最后,和 lowmemorykiller 一样,通过发送 SIGKILL 结束选中的进程。由于 oom_killer 与标准 Linux 内核并无不同,这里不再详细研究。

总结

本文研究了 Android 操作系统上的内存回收机制。主要包括 Application Framework 层的默认回收以及 Linux 内核中的 lowmemorykiller、OOM_killer。一般来说应用开发者并不需要控制或者修改系统的内存管理以及回收,但是深入理解这些系统级的管理 机制还是必要的,尤其有助于更加合理地设计应用程序,使应用程序的进程在其生命周期内高效地运行。而系统级开发者如果想要对内存管理机制进行优化,对原有 机制的理解则是必不可少的重要前提。

文章出处: IBM developerWorks

热点排行