AMS的进程管理

 Android将应用进程分为五大类,分别为Forground类、Visible类、Service类、Background类及Empty类。这五大类划分各有规则。

Forground类进程

该类进程重要性最高,想成为这一类进程需要满足下面的属性:

1.含有一个前端的Activity(OnResume函数被调用过了,或者说当前正在显示的那个Activity)

2.含有一个与前端Activity bind 的Service

3.含有一个调用了startForground的Service,或者该进程的Service正在调用其生命周期的函数(onCreate、onStart、onDestroy)

4.该进程含有一个BroadcastReceiver实例并且正在执行onReceive函数

Visible类进程

这类进程没有处于前端的组件,但是用户仍然能看到它们,此类进程包括两种:

1.含有一个仅onPause被调用的Activity(即它还在前台,只不过部分界面被遮住)

2.包含一个Service,并且该Service和一个Visible的Activity绑定

Service类进程: 该类进程包含一个Service,此Service通过startService启动,并且不属于前面两类进程,如MediaScannerService。

Background进程: 包含当前不可见的Activity(onStop被调用过),系统保存这些进程到一个LRU(最近最少使用)列表,当系统需要内存时,LRU里的进程将被杀死。

Empty进程: 不包含任何组件,系统保留它们仅仅是当需要的时候为了省去fork进程,创建Android运行环境等一系列漫长而艰苦的工作。

 其实Android对于进程的划分是根据oom_adj值来划分的,种类也多得多,Android是通过设置进程的oom_adj值来进行进程的调度的(kernel在OOM情况下会根据进程的oom_adj值来选择杀死一些进程)。其中Android在linux的下新增了一个LMK(low memory killer)的工作方式。LMK的职责是根据当前内存大小去杀死对应oom_adj及以上的进程以回收内存。这里就对应关键的参数,即不同内存的阈值及oom_adj。

Android平台进程调度和OOM控制的API,它们统一被封装在Process.java中,关键代码如下:

 1 //设置线程的调度优先级
 2     public static final native void setThreadPriority(int tid, int priority)
 3             throws IllegalArgumentException, SecurityException;
 4 //设置线程的Group,实际上就是设置线程的调度策略
 5     public static final native void setThreadGroup(int tid, int group)
 6             throws IllegalArgumentException, SecurityException;
 7 //设置进程的调度策略,包括该进程的所有线程
 8     public static final native void setProcessGroup(int pid, int group)
 9             throws IllegalArgumentException, SecurityException;
10 //调整进程的oom_adj值
11     public static final native boolean setOomAdj(int pid, int amt);

下面是ProcessList类中对oom_adj,我们可以看到Android对进程的详细分类。

 1     // OOM adjustments for processes in various states:
 2 
 3     // Adjustment used in certain places where we don't know it yet.
 4     // (Generally this is something that is going to be cached, but we
 5     // don't know the exact value in the cached range to assign yet.)
 6     static final int UNKNOWN_ADJ = 16;
 7 
 8     // This is a process only hosting activities that are not visible,
 9     // so it can be killed without any disruption.
10     static final int CACHED_APP_MAX_ADJ = 15;
11     static final int CACHED_APP_MIN_ADJ = 9;
12 
13     // The B list of SERVICE_ADJ -- these are the old and decrepit
14     // services that aren't as shiny and interesting as the ones in the A list.
15     static final int SERVICE_B_ADJ = 8;
16 
17     // This is the process of the previous application that the user was in.
18     // This process is kept above other things, because it is very common to
19     // switch back to the previous app.  This is important both for recent
20     // task switch (toggling between the two top recent apps) as well as normal
21     // UI flow such as clicking on a URI in the e-mail app to view in the browser,
22     // and then pressing back to return to e-mail.
23     static final int PREVIOUS_APP_ADJ = 7;
24 
25     // This is a process holding the home application -- we want to try
26     // avoiding killing it, even if it would normally be in the background,
27     // because the user interacts with it so much.
28     static final int HOME_APP_ADJ = 6;
29 
30     // This is a process holding an application service -- killing it will not
31     // have much of an impact as far as the user is concerned.
32     static final int SERVICE_ADJ = 5;
33 
34     // This is a process with a heavy-weight application.  It is in the
35     // background, but we want to try to avoid killing it.  Value set in
36     // system/rootdir/init.rc on startup.
37     static final int HEAVY_WEIGHT_APP_ADJ = 4;
38 
39     // This is a process currently hosting a backup operation.  Killing it
40     // is not entirely fatal but is generally a bad idea.
41     static final int BACKUP_APP_ADJ = 3;
42 
43     // This is a process only hosting components that are perceptible to the
44     // user, and we really want to avoid killing them, but they are not
45     // immediately visible. An example is background music playback.
46     static final int PERCEPTIBLE_APP_ADJ = 2;
47 
48     // This is a process only hosting activities that are visible to the
49     // user, so we'd prefer they don't disappear.
50     static final int VISIBLE_APP_ADJ = 1;
51 
52     // This is the process running the current foreground app.  We'd really
53     // rather not kill it!
54     static final int FOREGROUND_APP_ADJ = 0;
55 
56     // This is a process that the system or a persistent process has bound to,
57     // and indicated it is important.
58     static final int PERSISTENT_SERVICE_ADJ = -11;
59 
60     // This is a system persistent process, such as telephony.  Definitely
61     // don't want to kill it, but doing so is not completely fatal.
62     static final int PERSISTENT_PROC_ADJ = -12;
63 
64     // The system process runs at the default adjustment.
65     static final int SYSTEM_ADJ = -16;
66 
67     // Special code for native processes that are not being managed by the system (so
68     // don't have an oom adj assigned by the system).
69     static final int NATIVE_ADJ = -17;

   不同内存手机的阈值也被定义在ProcessList中:

 1 //LMK设置的六个oom_adj
 2     private final int[] mOomAdj = new int[] {
 3             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
 4             BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
 5     };
 6     // These are the low-end OOM level limits.  This is appropriate for an
 7     // HVGA or smaller phone with less than 512MB.  Values are in KB.
 8     private final int[] mOomMinFreeLow = new int[] {
 9             12288, 18432, 24576,
10             36864, 43008, 49152
11     };
12     // These are the high-end OOM level limits.  This is appropriate for a
13     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
14     private static final int[] mOomMinFreeHigh = new int[] {
15             73728, 92160, 110592,
16             129024, 147456, 184320
17     };

另外在ProcessRecord中也定义了较多成员用于进程管理,就不列出来了。

下面就是AMS进程管理函数的分析了。

在AMS中,主要是两个函数来管理进程。分别为:updateLruProcessLocked 和 updateOomAdjLocked。

updateLruProcessLocked

Android所有应用进程(包括system_server)的ProcessRecord信息都保存在mPidsSelfLocked成员中,除此之外还有一个成员变量mLruProcesses也用于保存ProcessRecord。mLruProcesses的类型虽然是ArrayList,但其内部成员却是按照ProcessRecord的lruWeight大小排序的。在运行过程中,AMS会根据lruWeight的变化调整mLruProcesses成员的位置。updateLruProcessLocked的主要工作是根据app的lruWeight值调整它在数组中的位置。lruWeight越大,其在数组中的位置就越靠后。如果该app和某些Service或ContentProvider有交互关系,那就连同这些Service或ContentProvider所在进程调节lruWeight值。

updateOomAdjLocked

在updateOomAdjLocked函数中,AMS做了比较多事,都是为了最终调用computeOomAdjLocked函数计算某个进程的oom_adj和调度策略来完成对应用进程的管理,这之间4.0增加了一个接口类ComponentCallbacks2,定义了一个函数onTrimMemory,主要通知应用进程进行一定的内存释放。AMS的进程管理核心还是在computeOomAdjLocked里,computeOomAdjLocked就是一个算法,就是根据各种情况来设置几个值,这个调整的算法改进变动的可能性还是比较大的。Android在什么情况下会进行进程的调度呢?

1 bindBackupAgent(ApplicationInfo ,int )
2 bindService(IApplicationThread,Ibinder,Intent,String,IService)
3 bringDownServiceLocked(ServiceRecord,boolean)
4 getContentProviderImpl(IApplicationThread,String)
5 publishContentProviders()
6 removeConnectionLocked()
...

 

posted @ 2015-05-04 14:16  Simba.Chen  阅读(1730)  评论(0编辑  收藏  举报