Android Low Memory Killer

Android的Low Memory Killer是在标准linux kernel的OOM基础上修改而来的一种内存管理机制,当系统内存不足时,杀死Bad进程释放其内存。
Bad进程的选择标准有两个:oom_adj和占用内存的大小。oom_adj代表进程的优先级,数值越大,优先级越高,对应每个oom_adj都有一个空闲内存的阈值。

Android系统会对进程的重要性进行评估,并将重要性以“oom_adj”这个数值表示出来,赋予各个进程。系统会根据“oom_adj”来判断需要优先结束哪些进程,
一般来说,“oom_adj”的值越大,该进程被系统选中终止的可能就越高,前台程序的“oom_adj”值为0,这意味着它不会被系统终止。

Android将进程分为6个等级,foreground(前台进程)、visible(可见进程)、secondary server(次要服务)、hidden(后台进程)、content provider(内容供应节点)、empty(空进程)它们按优先级顺序由高到低依次是:

结束进程的顺序:Empty>Content Provider>Hidden>Secondary Server>Visible>Foreground。

Low Memory Killer与OOM的区别

OOM即Out of Memory是标准linux Kernel的一种内存管理机制,Low Memory Killer在它基础上作了改进:

1.OOM基于多个标准给每个进程打分,分最高的进程将被杀死;Low MemoryKiller则用oom_adj和占用内存的大小来选择Bad进程,

2.OOM在内存分配不足时调用,而Low Memory Killer每隔一段时间就会检查,一旦发现空闲内存低于某个阈值,则杀死Bad进程。

lowmem_minfree保存空闲内存的阈值,单位是一个页面4K,lowmem_adj保存每个阈值对应的优先级。
lowmem_shrink首先计算当前空闲内存的大小,如果小于某个阈值,则以该阈值对应的优先级为基准,遍历各个进程,计算每个进程占用内存的大小,找出优先级大于基准优先级的进程,在这些进程中选择优先级最大的杀死,如果优先级相同,则选择占用内存最多的进程。

lowmem_shrink杀死进程的方法是向进程发送一个不可以忽略或阻塞的SIGKILL信号:

force_sig(SIGKILL,selected);

进程oom_adj同样可以进行设置,通过write /proc//oom_adj ,在init.rc中,init进程的pid为1,omm_adj被配置为-16,永远不会被杀死。

   # Set init its forked children's oom_adj.
   write /proc/1/oom_adj -16
static short lowmem_adj[6] = {
    0,
    1,
    6,
    12,
};
static int lowmem_adj_size = 4;
static int lowmem_minfree[6] = {
    3 * 512,    /* 6MB */
    2 * 1024,   /* 8MB */
    4 * 1024,   /* 16MB */
    16 * 1024,  /* 64MB */
};

cat /sys/module/lowmemorykiller/parameters/minfree
18432,23040,27648,32256,55296,80640
以上数字的单位是page. 1 page = 4 kb
对应的就是(MB): 72,90,108,216,216,315

用户接口

设置空闲内存阈值的接口:/sys/module/lowmemorykiller/parameters/minfree,
设置对应优先级的接口:/sys/module/lowmemorykiller/parameters/adj,
设置各个进程优先级的接口:/proc/<进程pid>/oom_adj。

一 : 前台进程 (Active Process): oom_adj为0

         前台进程包括 : 1 : 活动 正在前台接收用户输入  

            2:活动、服务与广播接收器正在执行一个onReceive事件的处理函数

            3: 服务正在运行 onStart、onCreate或onDestroy事件处理函数。

二 : 已启动服务的进程(Started Service Process) :oom_adj值为0,这类进程包含一个已启动的服务。

服务并不直接与用户输入交互,因此服务的优先级低于可见活动的优先级,但是,已启动服务的进程任被认为是前台进程,只有在活动以及可见活动需要资源时,已启动服务的进程才会被杀死。

三 :可见进程 (Visible Process): oom_adj 为 1。活动是可见的,但并不在前台,或者不响应用户的输入。例如,活动被非全屏或者透明的活动所遮挡。

四 :后台进程 (Backgroud Process): oom_adj 值为 2,这类进程不包含任何可见的活动与启动的服务。通常大量后台进程存在时,系统会采用(last-seen-first-kill)后见先杀的方式,释放资源为前台进程使用。

五 :主界面 (home process): oom_adj 为 4

六 :隐藏进程 (hidden process): oom_adj为 7

七 :内容提供者 (content provider):oom_adj 为 14

八 :空进程 (Empty process):oom_adj为 15

你可能感兴趣的:(Android Low Memory Killer)