Android Framework学习 之 Android原生进程调度方法
简单回答:
安卓原生的进程调度方法就是 通过 oomadj 和 procState 来进行进程调度。
真正实现是在lmkd,lmkd根据内存情况选择去杀死进程。杀死的依据就是根据adj值得大小,adj的值越大,优先级越低,越容易被杀掉。
顺便说一下,AMS同时维护一个list:mLruProcesses,Lru就是进程调度算法。
什么是LRU算法?简单说:就是淘汰最长时间为使用的进程。
在一个正常运行的系统中,缓存进程是内存管理中 唯一 涉及到的进程:一个运行良好的系统将始终具有多个缓存进程(为了更高效的切换应用),并根据需要定期终止最旧的进程。只有在非常严重(并且不可取)的情况下,系统才会到达这样一个点,此时所有的缓存进程都已被终止,并且必须开始终止服务进程。
Android系统回收后台进程的参考条件:
- LRU算法:自下而上开始终止,先回收最老的进程。越老的进程近期内被用户再次使用的几率越低。杀死的进程越老,对用户体验的影响就越小。
- 回收收益:系统总是倾向于杀死一个能回收更多内存的进程,因为在它被杀时会为系统提供更多内存增益,从而可以杀死更少的进程。杀死的进程越少,对用户体验的影响就越小。换句话说,应用进程在整个LRU列表中消耗的内存越少,保留在列表中并且能够快速恢复的机会就越大。
这里只介绍AMS的进程相关的成员变量:
- mProcessNames:数据类型为ProcessMap,以进程名和userId为key来记录ProcessRecord;
- 添加进程,addProcessNameLocked()
- 删除进程,removeProcessNameLocked()
- mPidsSelfLocked: 数据类型为SparseArray,以进程pid为key来记录ProcessRecord;
- startProcessLocked(),移除已存在进程,增加新创建进程pid信息;
- removeProcessLocked,processStartTimedOutLocked,cleanUpApplicationRecordLocked移除进程;
- mLruProcesses:数据类型为ArrayList,以进程最近使用情况来排序记录ProcessRecord;
- 其中第一个元素代表的便是最近最少使用的进程;
- updateLruProcessLocked()更新进程队列位置;
- mRemovedProcesses:数据类型为ArrayList,记录所有需要强制移除的进程;
- mProcessesToGc:数据类型为ArrayList,记录系统进入idle状态需执行gc操作的进程;
- mPendingPssProcesses:数据类型为ArrayList,记录将要收集内存使用数据PSS的进程;
- mProcessesOnHold:数据类型为ArrayList,记录刚开机过程,系统还没与偶准备就绪的情况下, 所有需要启动的进程都放入到该队列;
- mPersistentStartingProcesses:数据类型ArrayList,正在启动的persistent进程;
- mHomeProcess: 记录包含home Activity所在的进程;
- mPreviousProcess:记录用户上一次刚访问的进程;其中mPreviousProcessVisibleTime记录上一个进程的用户访问时间;
- mProcessList: 数据类型ProcessList,用于进程管理,Adj常量定义位于该文件;
其中最为常见的是mProcessNames,mPidsSelfLocked,mLruProcesses这3个对象;
二. ADJ的更新时机
先来说说哪些场景下都会触发updateOomAdjLocked
来更新进程adj:
2.1 Activity
- ASS.realStartActivityLocked: 启动Activity
- AS.resumeTopActivityInnerLocked: 恢复栈顶Activity
- AS.finishCurrentActivityLocked: 结束当前Activity
- AS.destroyActivityLocked: 摧毁当前Activity
2.2 Service
位于ActiveServices.java
- realStartServiceLocked: 启动服务
- bindServiceLocked: 绑定服务(只更新当前app)
- unbindServiceLocked: 解绑服务 (只更新当前app)
- bringDownServiceLocked: 结束服务 (只更新当前app)
- sendServiceArgsLocked: 在bringup或则cleanup服务过程调用 (只更新当前app)
2.3 broadcast
- BQ.processNextBroadcast: 处理下一个广播
- BQ.processCurBroadcastLocked: 处理当前广播
- BQ.deliverToRegisteredReceiverLocked: 分发已注册的广播 (只更新当前app)
2.4 ContentProvider
- AMS.removeContentProvider: 移除provider
- AMS.publishContentProviders: 发布provider (只更新当前app)
- AMS.getContentProviderImpl: 获取provider (只更新当前app)
2.5 Process
位于ActivityManagerService.java
- setSystemProcess: 创建并设置系统进程
- addAppLocked: 创建persistent进程
- attachApplicationLocked: 进程创建后attach到system_server的过程;
- trimApplications: 清除没有使用app
- appDiedLocked: 进程死亡
- killAllBackgroundProcesses: 杀死所有后台进程.即(ADJ>9或removed=true的普通进程)
- killPackageProcessesLocked: 以包名的形式 杀掉相关进程;