目录
一:概念
1.1 进程
进程是系统进行资源分配的最小单位,线程是CUP调度的最小单位。线程依赖于进程而存在,一个进程可以有多个线程。进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间。而线程是共享进程中的数据的,使用相同的地址空间。一般情况下,一个APP是属于一个进程的,但是可以在AndroidManifest中对application或者四大组件进行 android:process 属性设置,为其分配进程。
1.2 进程优先级
进程的优先级反应了系统对于进程重要性的判定。
在Android系统中,进程的优先级影响着以下三个因素:
- 当内存紧张时,系统对于进程的回收策略
- 系统对于进程的CPU调度策略
- 虚拟机对于进程的内存分配和垃圾回收策略
1.2.1 adj
对于每一个运行中的进程,Linux内核都通过proc文件系统暴露这样一个文件来允许其他程序修改指定进程的优先级:/proc/[pid]/oom_score_adj。
这个文件允许的值的范围是:-1000 ~ +1000之间。值越小,表示进程越重要。
当内存非常紧张时,系统便会遍历所有进程,以确定哪个进程需要被杀死以回收内存,此时便会读取oom_score_adj
这个文件的值。
在ProcessStateRecord中,定义了一些全局变量来保存相关的值
private int mMaxAdj = ProcessList.UNKNOWN_ADJ;
private int mCurRawAdj = ProcessList.INVALID_ADJ;
private int mSetRawAdj = ProcessList.INVALID_ADJ;
private int mCurAdj = ProcessList.INVALID_ADJ;
private int mSetAdj = ProcessList.INVALID_ADJ;
maxAdj
指定了该进程允许的oom_score_adj
最大值。这个属性主要是给系统应用和常驻内存的进程使用,这些进程的优先级的计算方法与应用进程的计算方法不一样,通过设定maxAdj
保证这些进程一直拥有较高的优先级 。
curXXX
这一组记录了这一次优先级计算的结果。在计算完成之后,会将curXXX
复制给对应的setXXX
这一组上进行备份。
xxxRawAdj记录了没有经过限制的adj值,“没有经过限制”是指这其中的值可能是超过了oom_score_adj
文件所允许的范围。
1.2.2 Schedule Group
内核负责了进程的CPU调度,所有运行中的进程并非能平等的能获取相等的时间片。在ProcessStateRecord中,通过Schedule Group来记录进程的调度组:
int curSchedGroup; // Currently desired scheduling class
int setSchedGroup; // Last set to background scheduling class
它们可能的取值定义在ProcessList.java中:
// Activity manager's version of Process.THREAD_GROUP_BACKGROUND
static final int SCHED_GROUP_BACKGROUND = 0;
// Activity manager's version of Process.THREAD_GROUP_RESTRICTED
static final int SCHED_GROUP_RESTRICTED = 1;
// Activity manager's version of Process.THREAD_GROUP_DEFAULT
static final int SCHED_GROUP_DEFAULT = 2;
// Activity manager's version of Process.THREAD_GROUP_TOP_APP
public static final int SCHED_GROUP_TOP_APP = 3;
// Activity manager's version of Process.THREAD_GROUP_TOP_APP
// Disambiguate between actual top app and processes bound to the top app
static final int SCHED_GROUP_TOP_APP_BOUND = 4;
1.2.3 ProcessState
进程的状态会影响虚拟机对于进程的内存分配和垃圾回收策略,进程状态的可能值定义在ActivityManager中
@IntDef(flag = false, prefix = { "PROCESS_STATE_" }, value = {
PROCESS_STATE_UNKNOWN, // -1
PROCESS_STATE_PERSISTENT, // 0
PROCESS_STATE_PERSISTENT_UI,
PROCESS_STATE_TOP,
PROCESS_STATE_BOUND_TOP,
PROCESS_STATE_FOREGROUND_SERVICE,
PROCESS_STATE_BOUND_FOREGROUND_SERVICE,
PROCESS_STATE_IMPORTANT_FOREGROUND,
PROCESS_STATE_IMPORTANT_BACKGROUND,
PROCESS_STATE_TRANSIENT_BACKGROUND,
PROCESS_STATE_BACKUP,
PROCESS_STATE_SERVICE,
PROCESS_STATE_RECEIVER,
PROCESS_STATE_TOP_SLEEPING,
PROCESS_STATE_HEAVY_WEIGHT,
PROCESS_STATE_HOME,
PROCESS_STATE_LAST_ACTIVITY,
PROCESS_STATE_CACHED_ACTIVITY,
PROCESS_STATE_CACHED_ACTIVITY_CLIENT,
PROCESS_STATE_CACHED_RECENT,
PROCESS_STATE_CACHED_EMPTY,
})
二:优先级的更新
2.1 优先级更新的依据
Android组件与进程的关系:
- 每一个Android的应用进程中,都可能包含四大组件中的一种或者多种。
- 对于运行中的Service和ContentProvider来说,可能有若干个客户端进程正在对其使用。
- 应用进程是由ActivityManagerService发送请求让zygote创建的,并且ActivityManagerService中对于每一个运行中的进程都有一个
ProcessRecord
对象与之对应。
进程和组件息息相关,所有这些组件的状态就是其所在进程优先级的决定性因素。 组件的状态是指:
- Activity是否在前台,用户是否可见
- Service正在被哪些客户端使用
- ContentProvider正在被哪些客户端使用
- BroadcastReceiver是否正在接受广播
PS:Process相关信息保存见下表
2.2 更新优先级
2.2.1 优先级更新时机
ActivityManagerService中有如下两个方法用来更新进程的优先级:
final boolean updateOomAdjLocked(ProcessRecord app, @OomAdjReason int oomAdjReason)
final void updateOomAdjLocked(@OomAdjReason int oomAdjReason)
第一个方法是针对指定的进程更新优先级。第二个是对所有进程更新优先级。
在下面的这些情况下,系统需要对指定的进程更新优先级:
- 当有一个新的进程开始使用本进程中的ContentProvider
- 当本进程中的一个Service被其他进程bind或者unbind
- 当本进程中的Service的执行完成或者退出了
- 当本进程中一个BroadcastReceiver正在接受广播
- 当本进程中的BackUpAgent启动或者退出了
在有些情况下,系统需要对所有进程的优先级进行更新,譬如:
- 当有一个新的进程启动时
- 当有一个进程退出时
- 当系统在清理后台进程时
- 当有一个进程被标记为前台进程时
- 当有一个进程进入或者退出cached状态时
- 当系统锁屏或者解锁时
- 当有一个Activity启动或者退出时
- 当系统正在处理一个广播事件时
- 当前台Activity发生改变时
- 当有一个Service启动时
2.2.2 优先级的计算
优先级的计算是通过OomAdjuster.computeOomAdjLSP函数来实现的,简化流程图如下
1. 通过 mAdjSeq 确认此次计算是否有必要,是否已经计算过;
2. 判断是否为空进程;
3. 当maxAdj<=FOREGROUND_APP_ADJ(都是重要的系统进程)根据是否显示UI、是否为topApp等条件设置adj、procState等,然后return;
4. 前台进程相关处理,根据不同场景(远程动画、接收广播、运行service等)设置前台进程adj、adjType、procState、schedGroup;
5. 如果不是前台进程,但有cache activities,通过 computeOomAdjFromActivitiesIfNecessary()确定进程cachedadj等;
6. 分别根据adj是否大于PERCEPTIBLE_APP_ADJ、PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ以及是否是重量级进程/HOME进程/Previous进程等,再根据进程具体状态进一步确认adj、adjType、procState、schedGroup等值;
7. 确认是否为backup进程;
8. 遍历在进程上运行所有services,根据service的运行状态修正当前进程adj等值。再遍历引用service的所有client,根据client的运行状态进一步修正当前进程adj等值;
9. 同service,遍历进程上关联的providers,根据providers以及客户端进一步修正adj值;
10. 收尾,进一步确认:
10.1 当一个进程20s内调用contentProvider,把进程优先级保持在一个较高的水平;
10.2 procState >= PROCESS_STATE_CACHED_EMPTY时进一步调整procState和adjType;
10.3 当adj==SERVICE_ADJ,确认是否在serviceb中,如果是adj改成SERVICE_B_ADJ;
10.4 灭屏状态下限制绑定的前台服务进程,设置其schedGroup为SCHED_GROUP_RESTRICTED;
private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
boolean computeClients) {
...
//通过mAdjSeq判断该进程是否已经处理
if (mAdjSeq == state.getAdjSeq()) {
if (state.getAdjSeq() == state.getCompletedAdjSeq()) {//已经完成adj的计算,直接返回
return false;
} else {//未完成,将containsCycle置为true
state.setContainsCycle(true);
mProcessesInCycle.add(app);
return false;
}
}
//进程中没有任何线程,是个空进程,设置adj为CACHED_APP_MAX_ADJ
if (app.getThread() == null) {
state.setAdjSeq(mAdjSeq);
state.setCurrentSchedulingGroup(SCHED_GROUP_BACKGROUND);
state.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
state.setCurAdj(CACHED_APP_MAX_ADJ);
state.setCurRawAdj(CACHED_APP_MAX_ADJ);
state.setCompletedAdjSeq(state.getAdjSeq());
state.setCurCapability(PROCESS_CAPABILITY_NONE);
return false;
}
//如果不是空进程,初始化
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN);
...
final int logUid = mService.mCurOomAdjUid;
//暂存进程现有的adj、状态等
int prevAppAdj = state.getCurAdj();
int prevProcState = state.getCurProcState();
int prevCapability = state.getCurCapability();
final ProcessServiceRecord psr = app.mServices;
//处理maxAdj在0以下的重要的系统进程
if (state.getMaxAdj() <= FOREGROUND_APP_ADJ) {
...
state.setAdjType("fixed");
state.setAdjSeq(mAdjSeq);
state.setCurRawAdj(state.getMaxAdj());
state.setHasForegroundActivities(false);
state.setCurrentSchedulingGroup(SCHED_GROUP_DEFAULT);
state.setCurCapability(PROCESS_CAPABILITY_ALL); // BFSL allowed
state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
//系统进程可以显示UI,当离开UI之后,系统想trim内存。systemNoUi用来确定是否正在显示UI
state.setSystemNoUi(true);
if (app == topApp) {//前台进程
state.setSystemNoUi(false);
state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
state.setAdjType("pers-top-activity");
} else if (state.hasTopUi()) {//进程有前台UI
state.setSystemNoUi(false);
state.setAdjType("pers-top-ui");
} else if (state.getCachedHasVisibleActivities()) {//cache中有可见的Activity
state.setSystemNoUi(false);
}
if (!state.isSystemNoUi()) {//该进程正在显示UI
if (mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE
|| state.isRunningRemoteAnimation()) {
//亮屏或者正在播放动画,设置SchedulingGroup为SCHED_GROUP_TOP_APP
state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI);
state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
} else {
//灭屏,设置SchedulingGroup为SCHED_GROUP_RESTRICTED,限制UI分发
state.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
state.setCurrentSchedulingGroup(SCHED_GROUP_RESTRICTED);
}
}
state.setCurRawProcState(state.getCurProcState());
state.setCurAdj(state.getMaxAdj());
//处理完成,将completedAdjSeq设置为当前进程adjSeq
state.setCompletedAdjSeq(state.getAdjSeq());
//如果curAdj小于prevAppAdj,则此进程已升级
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState;
}
//处理adj>0的进程,默认将systemNoUi设为false
state.setSystemNoUi(false);
//保存top进程的procState(该值只有两个取值PROCESS_STATE_TOP和PROCESS_STATE_TOP_SLEEPING)
final int PROCESS_STATE_CUR_TOP = mService.mAtmInternal.getTopProcessState();
...
//根据不同场景设置前台进程的adjType,并更新adj、schedGroup、procState等信息
if (app == topApp && PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {//前台进程
...
} else if (state.isRunningRemoteAnimation()) {//正在运行远程动画
...
} else if (app.getActiveInstrumentation() != null) {//与测试相关场景
...
} else if (state.getCachedIsReceivingBroadcast(mTmpSchedGroup)) {//cache正在接收广播
...
} else if (psr.numberOfExecutingServices() > 0) {//正在运行Service调用
...
} else if (app == topApp) {//前台进程,但是procState是PROCESS_STATE_TOP_SLEEPING
...
} else {//空进程
...
}
//非前台进程,但是cache有Activity,需要继续确定adj
if (!foregroundActivities && state.getCachedHasActivities()) {
// mTmpComputeOomAdjWindowCallback计算adj时的回调
// computeOomAdjFromActivitiesIfNecessary判断是否执行过
// 如果未执行过,则调用callback.initialize把adj/prostate存储
// 然后判断是否visible(adj=VISIBLE_APP_ADJ)、
// paused/stop(adj=PERCEPTIBLE_APP_ADJ)、other(procState=PROCESS_STATE_CACHED_ACTIVITY)
// 然后把adj/prostate赋值给app.mCachedAdj/app.mCachedProcState
// 如果执行过,则直接返回
state.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback,
adj, foregroundActivities, hasVisibleActivities, procState, schedGroup,
appUid, logUid, PROCESS_STATE_CUR_TOP);
//把计算结果赋值
adj = state.getCachedAdj();
...
schedGroup = state.getCachedSchedGroup();
}
//如果是有recentTask的cache进程,设置procState为PROCESS_STATE_CACHED_RECENT
if (procState > PROCESS_STATE_CACHED_RECENT && state.getCachedHasRecentTasks()) {
procState = PROCESS_STATE_CACHED_RECENT;
state.setAdjType("cch-rec");
}
final boolean hasForegroundServices = psr.hasForegroundServices();
final boolean hasNonShortForegroundServices = psr.hasNonShortForegroundServices();
final boolean hasShortForegroundServices = hasForegroundServices
&& !psr.areAllShortForegroundServicesProcstateTimedOut(now);
//优先级大于可感知进程或级别高于前台service的处理
if (adj > PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_FOREGROUND_SERVICE) {
...
if (hasForegroundServices && hasNonShortForegroundServices) {//带前台service且service的flag没有FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
adjType = "fg-service";
newAdj = PERCEPTIBLE_APP_ADJ;
newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
capabilityFromFGS |= PROCESS_CAPABILITY_BFSL;
} else if (hasShortForegroundServices) {//service的flag有FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
adjType = "fg-service-short";
newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1;
newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
} else if (state.hasOverlayUi()) {//有overlay ui
adjType = "has-overlay-ui";
newAdj = PERCEPTIBLE_APP_ADJ;
newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
}
//adjType不为空,更新adj、procState、schedGroup等信息
if (adjType != null) {
adj = newAdj;
procState = newProcState;
state.setAdjType(adjType);
state.setCached(false);
schedGroup = SCHED_GROUP_DEFAULT;
}
}
//从前台进程切换到带前台service,允许在15s内保持较高的优先级,保证其完成一些剩余操作
if (psr.hasForegroundServices() && adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
&& (state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
if (psr.hasNonShortForegroundServices()) {
adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
state.setAdjType("fg-service-act");
} else {
adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1;
state.setAdjType("fg-service-short-act");
}
}
//从前台进程切换到带可感知的Service(Service连接时有Context.BIND_ALMOST_PERCEPTIBLE 此flag),允许在15s内保持较高的优先级,保证其完成一些剩余操作
if (psr.hasTopStartedAlmostPerceptibleServices()
&& (adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2)
&& (state.getLastTopTime()
+ mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2;
state.setAdjType("top-ej-act");
}
//优先级大于可感知进程或级别高于后台进程
if (adj > PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
if (state.getForcingToImportant() != null) {//一般用于toast
adj = PERCEPTIBLE_APP_ADJ;
procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
state.setCached(false);
state.setAdjType("force-imp");
state.setAdjSource(state.getForcingToImportant());
schedGroup = SCHED_GROUP_DEFAULT;
}
}
//重量级后台进程,把adj和procState都拉回到 heavy weight水平
if (state.getCachedIsHeavyWeight()) {
if (adj > HEAVY_WEIGHT_APP_ADJ) {
adj = HEAVY_WEIGHT_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("heavy");
}
if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
state.setAdjType("heavy");
}
}
//HOME进程,将其拉回HOME_APP_ADJ
if (state.getCachedIsHomeProcess()) {
if (adj > HOME_APP_ADJ) {
adj = HOME_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("home");
}
if (procState > ActivityManager.PROCESS_STATE_HOME) {
procState = ActivityManager.PROCESS_STATE_HOME;
state.setAdjType("home");
}
}
//前一个进程仍然带有activity,在60s内保持一个较高的优先级(PREVIOUS_APP_ADJ),超过60s则设置成CACHED_APP_MIN_ADJ
if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) {
if (procState >= PROCESS_STATE_LAST_ACTIVITY
&& state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY
&& (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) < now) {
procState = PROCESS_STATE_LAST_ACTIVITY;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("previous-expired");
adj = CACHED_APP_MIN_ADJ;
} else {
if (adj > PREVIOUS_APP_ADJ) {
adj = PREVIOUS_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("previous");
}
if (procState > PROCESS_STATE_LAST_ACTIVITY) {
procState = PROCESS_STATE_LAST_ACTIVITY;
state.setAdjType("previous");
}
}
}
//当进程service或者provider被其他进程使用时,需要继续调整adj,没有没有,则使用计算出来的值。如果我们由于循环而重新评估,使用之前计算的值。
if (cycleReEval) {
procState = Math.min(procState, state.getCurRawProcState());
adj = Math.min(adj, state.getCurRawAdj());
schedGroup = Math.max(schedGroup, state.getCurrentSchedulingGroup());
}
//前面计算出来的adj/procState暂存到ProcessStateRecord的参数里
state.setCurRawAdj(adj);
state.setCurRawProcState(procState);
state.setHasStartedServices(false);
state.setAdjSeq(mAdjSeq);
//处理service中备份的进程,使备份进程保持一个较高的优先级(BACKUP_APP_ADJ)
final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId);
if (backupTarget != null && app == backupTarget.app) {
if (adj > BACKUP_APP_ADJ) {
adj = BACKUP_APP_ADJ;
if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
}
state.setAdjType("backup");
state.setCached(false);
}
if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
procState = ActivityManager.PROCESS_STATE_BACKUP;
state.setAdjType("backup");
}
}
/**************以下为service连接相关的处理逻辑***************/
boolean boundByNonBgRestricted = state.isCurBoundByNonBgRestrictedApp();
boolean scheduleLikeTopApp = false;
//遍历adj>前台进程的进程中正在运行的service,根据这些service进一步更新当前进程的adj
for (int is = psr.numberOfRunningServices() - 1;
is >= 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
is--) {
ServiceRecord s = psr.getRunningServiceAt(is);
if (s.startRequested) {//如果服务启动,则设置procState为PROCESS_STATE_SERVICE
state.setHasStartedServices(true);
if (procState > PROCESS_STATE_SERVICE) {
procState = PROCESS_STATE_SERVICE;
state.setAdjType("started-services");
}
//有显示的UI并且不是home,则标记cch-started-ui-services
if (!s.mKeepWarming && state.hasShownUi() && !state.getCachedIsHomeProcess()) {
if (adj > SERVICE_ADJ) {
state.setAdjType("cch-started-ui-services");
}
} else {//如果上一次调用service的时间间隔超过30 min,则设置adj为SERVICE_ADJ
if (s.mKeepWarming
|| now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
if (adj > SERVICE_ADJ) {
adj = SERVICE_ADJ;
state.setAdjType("started-services");
state.setCached(false);
}
}
if (adj > SERVICE_ADJ) {
state.setAdjType("cch-started-services");
}
}
}
//service运行在前台,主要更新capabilityFromFGS
if (s.isForeground) {
final int fgsType = s.foregroundServiceType;
...
}
//该服务还被其他进程连接时,遍历所有连接该service的进程,进行adj计算
ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
for (int conni = serviceConnections.size() - 1;
conni >= 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
conni--) {
//获取这个服务链接的客户端进程
ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
for (int i = 0;
i < clist.size() && (adj > FOREGROUND_APP_ADJ
|| schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
i++) {
ConnectionRecord cr = clist.get(i);
if (cr.binding.client == app) {//客户端进程是自己,不处理
continue;
}
boolean trackedProcState = false;
ProcessRecord client = cr.binding.client;//获取客户端的ProcessRecord
...
final ProcessStateRecord cstate = client.mState;//获取客户端的ProcessStateRecord
//传入的参数,是否计算客户端的adj,如果更新所有进程,则为true
if (computeClients) {
computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now,
cycleReEval, true);
} else {
cstate.setCurRawAdj(cstate.getCurAdj());
cstate.setCurRawProcState(cstate.getCurProcState());
}
...
//如果客户端进程不允许被冻结,则更新自身进程也不允许被冻结
if (client.mOptRecord.shouldNotFreeze()) {
app.mOptRecord.setShouldNotFreeze(true);
}
capability |= getBfslCapabilityFromClient(client);
//假如不包含BIND_WAIVE_PRIORITY的flag,即没有加入特殊标记不影响服务进程优先级
if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) {
if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
capability |= cstate.getCurCapability();
}
if ((cstate.getCurCapability()
& PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
// This is used to grant network access to Expedited Jobs.
if (cr.hasFlag(Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)) {
capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
}
} else {
capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
}
}
if ((cstate.getCurCapability()
& PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_IMPORTANT_FOREGROUND) {
// This is used to grant network access to User Initiated Jobs.
if (cr.hasFlag(Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)) {
capability |= PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
}
}
}
if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {
continue;
}
//如果客户端进程是cache,则认为是empty进程
if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
clientProcState = PROCESS_STATE_CACHED_EMPTY;
}
//BIND_ALLOW_OOM_MANAGEMENT代表保持服务受默认的服务管理器管理,当内存不足时,会销毁服务
String adjType = null;
if (cr.hasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT)) {
// Similar to BIND_WAIVE_PRIORITY, keep it unfrozen.
if (clientAdj < CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
}
//有显示的UI并且不是home,设置adjType为cch-bound-ui-services
if (state.hasShownUi() && !state.getCachedIsHomeProcess()) {
if (adj > clientAdj) {
adjType = "cch-bound-ui-services";
}
state.setCached(false);
clientAdj = adj;
clientProcState = procState;
} else {
//如果上一次调用service的时间间隔超过30min,则设置adjType为cch-bound-services
if (now >= (s.lastActivity
+ mConstants.MAX_SERVICE_INACTIVITY)) {
if (adj > clientAdj) {
adjType = "cch-bound-services";
}
clientAdj = adj;
}
}
}
//如果服务进程的优先级小于客户端进程,则提升优先级
if (adj > clientAdj) {
//有显示的UI并且不是home,且客户端进程优先级低于PERCEPTIBLE_APP_ADJ
if (state.hasShownUi() && !state.getCachedIsHomeProcess()
&& clientAdj > PERCEPTIBLE_APP_ADJ) {
if (adj >= CACHED_APP_MIN_ADJ) {
adjType = "cch-bound-ui-services";
}
} else {
int newAdj;
int lbAdj = VISIBLE_APP_ADJ; // lower bound of adj.
//BIND_ABOVE_CLIENT表明service比连接他的客户端更重要,则客户端进程adj赋值给当前进程
//BIND_IMPORTANT标识服务对客户端是非常重要的
if (cr.hasFlag(Context.BIND_ABOVE_CLIENT
| Context.BIND_IMPORTANT)) {
if (clientAdj >= PERSISTENT_SERVICE_ADJ) {//客户端adj大于PERSISTENT_SERVICE_ADJ的,则直接把客户端adj赋值给newAdj
newAdj = clientAdj;
} else {//persistent进程
// make this service persistent
newAdj = PERSISTENT_SERVICE_ADJ;
schedGroup = SCHED_GROUP_DEFAULT;
procState = ActivityManager.PROCESS_STATE_PERSISTENT;
cr.trackProcState(procState, mAdjSeq);
trackedProcState = true;
}
} else if (cr.hasFlag(Context.BIND_NOT_PERCEPTIBLE)
&& clientAdj <= PERCEPTIBLE_APP_ADJ
&& adj >= (lbAdj = PERCEPTIBLE_LOW_APP_ADJ)) {
//该进程的服务不是可感知服务,客户端进程优先级大于可感知,自身优先级低于感知程度低的进程(adj为250),则设置newAdj为250
newAdj = PERCEPTIBLE_LOW_APP_ADJ;
} else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)
&& cr.notHasFlag(Context.BIND_NOT_FOREGROUND)
&& clientAdj < PERCEPTIBLE_APP_ADJ
&& adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) {
//该进程的服务是几乎可感知的服务但是不是前台服务,客户端优先级大于可感知,自身优先级低于可感知,则设置newAdj为201
newAdj = PERCEPTIBLE_APP_ADJ + 1;
} else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)
&& cr.hasFlag(Context.BIND_NOT_FOREGROUND)
&& clientAdj < PERCEPTIBLE_APP_ADJ
&& adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) {
//该进程的服务是几乎可感知的服务但是不是前台服务,客户端优先级大于可感知,自身优先级低于托管服务进程优先级,则设置newAdj为227
newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 2;
} else if (cr.hasFlag(Context.BIND_NOT_VISIBLE)
&& clientAdj < PERCEPTIBLE_APP_ADJ
&& adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) {
//该进程的服务绑定状态BIND_NOT_VISIBLE,客户端优先级大于可感知,自身优先级低于可感知,则设置newAdj为200
newAdj = PERCEPTIBLE_APP_ADJ;
} else if (clientAdj >= PERCEPTIBLE_APP_ADJ) {
//客户端优先级低于可感知,则把客户端优先级赋值给newAdj
newAdj = clientAdj;
} else if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)
&& clientAdj <= VISIBLE_APP_ADJ
&& adj > VISIBLE_APP_ADJ) {
//如果是BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE类型的服务,客户端优先级大于可见进程优先级,自身优先级低于可见进程优先级,则把newAdj设置为100
newAdj = VISIBLE_APP_ADJ;
} else {
//如果自身优先级低于可见进程优先级,则把客户端优先级和可见进程优先级中优先级较低的值赋值给newAdj,如果自身优先级高于可见进程优先级,则把自身优先级赋值给newAdj
if (adj > VISIBLE_APP_ADJ) {
newAdj = Math.max(clientAdj, lbAdj);
} else {
newAdj = adj;
}
}
if (!cstate.isCached()) {//如果客户端进程状态是非cache,则自身也不能是cache
state.setCached(false);
}
if (adj > newAdj) {//如果自身优先级低于新优先级,则更新自身优先级
adj = newAdj;
state.setCurRawAdj(adj);
adjType = "service";
}
}
}
//根据不同的情况,更新schedGroup和clientProcState
if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND
| Context.BIND_IMPORTANT_BACKGROUND)) {
//这将把重要的绑定服务与顶级应用程序一视同仁,后者的行为可能与一般的前台工作不同。
final int curSchedGroup = cstate.getCurrentSchedulingGroup();
if (curSchedGroup > schedGroup) {
if (cr.hasFlag(Context.BIND_IMPORTANT)) {//重要绑定服务
schedGroup = curSchedGroup;
} else {
schedGroup = SCHED_GROUP_DEFAULT;
}
}
if (clientProcState < PROCESS_STATE_TOP) {//客户端进程非top进程
if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)) {
clientProcState = PROCESS_STATE_FOREGROUND_SERVICE;
} else if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
} else if (mService.mWakefulness.get()
== PowerManagerInternal.WAKEFULNESS_AWAKE
&& cr.hasFlag(Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE))
{
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
} else {
clientProcState =
PROCESS_STATE_IMPORTANT_FOREGROUND;
}
} else if (clientProcState == PROCESS_STATE_TOP) {//客户端进程是top进程
clientProcState = PROCESS_STATE_BOUND_TOP;
final boolean enabled = cstate.getCachedCompatChange(
CACHED_COMPAT_CHANGE_PROCESS_CAPABILITY);
if (enabled) {
if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
// TOP process passes all capabilities to the service.
capability |= cstate.getCurCapability();
} else {
// TOP process passes no capability to the service.
}
} else {
// TOP process passes all capabilities to the service.
capability |= cstate.getCurCapability();
}
}
} else if (cr.notHasFlag(Context.BIND_IMPORTANT_BACKGROUND)) {
if (clientProcState <
PROCESS_STATE_TRANSIENT_BACKGROUND) {
clientProcState =
PROCESS_STATE_TRANSIENT_BACKGROUND;
}
} else {
if (clientProcState <
PROCESS_STATE_IMPORTANT_BACKGROUND) {
clientProcState =
PROCESS_STATE_IMPORTANT_BACKGROUND;
}
}
if (schedGroup < SCHED_GROUP_TOP_APP
&& cr.hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP)
&& clientIsSystem) {
schedGroup = SCHED_GROUP_TOP_APP;
scheduleLikeTopApp = true;
}
if (!trackedProcState) {
cr.trackProcState(clientProcState, mAdjSeq);
}
if (procState > clientProcState) {
procState = clientProcState;
state.setCurRawProcState(procState);
if (adjType == null) {
adjType = "service";
}
}
if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND
&& cr.hasFlag(Context.BIND_SHOWING_UI)) {
app.setPendingUiClean(true);
}
if (adjType != null) {
state.setAdjType(adjType);
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE);
state.setAdjSource(client);
state.setAdjSourceProcState(clientProcState);
state.setAdjTarget(s.instanceName);
}
} else { //包含BIND_WAIVE_PRIORITY的flag
if (clientAdj < CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
}
}
if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) {
psr.setTreatLikeActivity(true);
}
final ActivityServiceConnectionsHolder a = cr.activity;
if (cr.hasFlag(Context.BIND_ADJUST_WITH_ACTIVITY)) {
if (a != null && adj > FOREGROUND_APP_ADJ
&& a.isActivityVisible()) {//自身优先级低于前台进程优先级且客户端的activity可见
adj = FOREGROUND_APP_ADJ;
state.setCurRawAdj(adj);
if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND)) {
if (cr.hasFlag(Context.BIND_IMPORTANT)) {
schedGroup = SCHED_GROUP_TOP_APP_BOUND;
} else {
schedGroup = SCHED_GROUP_DEFAULT;
}
}
state.setCached(false);
state.setAdjType("service");
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE);
state.setAdjSource(a);
state.setAdjSourceProcState(procState);
state.setAdjTarget(s.instanceName);
}
}
}
}
}
/**************以下为provider相关的处理逻辑***************/
//根据provider客户端的状态确定当前进程的adj,schedGroup和procState
//遍历与当前进程相关的所有provider
final ProcessProviderRecord ppr = app.mProviders;
for (int provi = ppr.numberOfProviders() - 1;
provi >= 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
provi--) {//非前台进程
ContentProviderRecord cpr = ppr.getProviderAt(provi);
for (int i = cpr.connections.size() - 1;
i >= 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
i--) {
ContentProviderConnection conn = cpr.connections.get(i);
ProcessRecord client = conn.client;
final ProcessStateRecord cstate = client.mState;
if (client == app) {//客户端是自己,不做处理
continue;
}
if (computeClients) {//传入的参数,是否计算客户端的adj,如果更新所有进程,则为true
computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now, cycleReEval, true);
} else {//保存客户端的adj和procState到ProcessStateRecord
cstate.setCurRawAdj(cstate.getCurAdj());
cstate.setCurRawProcState(cstate.getCurProcState());
}
if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {//是否在cycle内跳过
continue;
}
//临时保存客户端的adj和procState
int clientAdj = cstate.getCurRawAdj();
int clientProcState = cstate.getCurRawProcState();
...
if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
//客户端进程是cache进程,把clientProcState设置成PROCESS_STATE_CACHED_EMPTY
clientProcState = PROCESS_STATE_CACHED_EMPTY;
}
if (client.mOptRecord.shouldNotFreeze()) {
//客户端进程不允许冻结,则自身也不能被冻结
app.mOptRecord.setShouldNotFreeze(true);
}
...
String adjType = null;
if (adj > clientAdj) {//进程自身优先级低于客户端进程优先级
if (state.hasShownUi() && !state.getCachedIsHomeProcess()
&& clientAdj > PERCEPTIBLE_APP_ADJ) {//有显示的UI并且不是home,且客户端进程优先级低于PERCEPTIBLE_APP_ADJ
adjType = "cch-ui-provider";
} else {//进程自身优先级最高设置为FOREGROUND_APP_ADJ
adj = Math.max(clientAdj, FOREGROUND_APP_ADJ);
state.setCurRawAdj(adj);
adjType = "provider";
}
state.setCached(state.isCached() & cstate.isCached());//进程自身以及客户端进程都是cache,则设置进程状态是cache
}
if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) {//客户端进程优先级比前台服务进程优先级高
if (adjType == null) {
adjType = "provider";
}
if (clientProcState == PROCESS_STATE_TOP) {
clientProcState = PROCESS_STATE_BOUND_TOP;
} else {
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
}
}
conn.trackProcState(clientProcState, mAdjSeq);
if (procState > clientProcState) {//进程自身procState小于客户端进程procState,则把客户端procState赋值给自身procState
procState = clientProcState;
state.setCurRawProcState(procState);
}
if (cstate.getCurrentSchedulingGroup() > schedGroup) {
schedGroup = SCHED_GROUP_DEFAULT;
}
if (adjType != null) {
state.setAdjType(adjType);
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_PROVIDER_IN_USE);
state.setAdjSource(client);
state.setAdjSourceProcState(clientProcState);
state.setAdjTarget(cpr.name);
}
}
//provider有非framework层的外部进程依赖,保证其adj最大为FOREGROUND_APP_ADJ,procState最大为PROCESS_STATE_IMPORTANT_FOREGROUND
if (cpr.hasExternalProcessHandles()) {
if (adj > FOREGROUND_APP_ADJ) {
adj = FOREGROUND_APP_ADJ;
state.setCurRawAdj(adj);
schedGroup = SCHED_GROUP_DEFAULT;
state.setCached(false);
state.setAdjType("ext-provider");
state.setAdjTarget(cpr.name);
}
if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) {
procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
state.setCurRawProcState(procState);
}
}
}
/**************收尾工作,有些数据需要特殊限制*****************/
//如果上一次调用provider的时间间隔在20s以内,保持在一个较高的优先级
if (ppr.getLastProviderTime() > 0
&& (ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
if (adj > PREVIOUS_APP_ADJ) {
adj = PREVIOUS_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("recent-provider");
}
if (procState > PROCESS_STATE_LAST_ACTIVITY) {
procState = PROCESS_STATE_LAST_ACTIVITY;
state.setAdjType("recent-provider");
}
}
//对cache进程进一步细分
if (procState >= PROCESS_STATE_CACHED_EMPTY) {
if (psr.hasClientActivities()) {
procState = PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
state.setAdjType("cch-client-act");
} else if (psr.isTreatedLikeActivity()) {
procState = PROCESS_STATE_CACHED_ACTIVITY;
state.setAdjType("cch-as-act");
}
}
//针对服务进程做进一步细分
if (adj == SERVICE_ADJ) {
if (doingAll && !cycleReEval) {
//所有Service进程的前1/3为ServiceA,剩下为ServiceB
state.setServiceB(mNewNumAServiceProcs > (mNumServiceProcs / 3));
mNewNumServiceProcs++;
if (!state.isServiceB()) {
//ServiceA在低内存时,pss超过getCachedRestoreThresholdKb就会变成ServiceB
if (!mService.mAppProfiler.isLastMemoryLevelNormal()
&& app.mProfile.getLastPss()
>= mProcessList.getCachedRestoreThresholdKb()) {
state.setServiceHighRam(true);
state.setServiceB(true);
} else {
mNewNumAServiceProcs++;
}
} else {
state.setServiceHighRam(false);
}
}
if (state.isServiceB()) {如果是ServiceB,则设置adj为SERVICE_B_ADJ
adj = SERVICE_B_ADJ;
}
}
state.setCurRawAdj(adj);
adj = psr.modifyRawOomAdj(adj);
if (adj > state.getMaxAdj()) {//计算好的adj不能超过maxAdj
adj = state.getMaxAdj();
if (adj <= PERCEPTIBLE_LOW_APP_ADJ) {
schedGroup = SCHED_GROUP_DEFAULT;
}
}
//将绑定的前台服务放在一个特殊的计划组中,在屏幕关闭时获得额外限制
if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
&& mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
&& !scheduleLikeTopApp) {
if (schedGroup > SCHED_GROUP_RESTRICTED) {
schedGroup = SCHED_GROUP_RESTRICTED;
}
}
// apply capability from FGS.
if (psr.hasForegroundServices()) {
capability |= capabilityFromFGS;
}
capability |= getDefaultCapability(app, procState);
// Procstates below BFGS should never have this capability.
if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
capability &= ~PROCESS_CAPABILITY_BFSL;
}
//更新计算后的adj、capability、schedGroup、procState等信息到ProcessStateRecord中
state.setCurAdj(adj);
state.setCurCapability(capability);
state.setCurrentSchedulingGroup(schedGroup);
state.setCurProcState(procState);
state.setCurRawProcState(procState);
state.updateLastInvisibleTime(hasVisibleActivities);
state.setHasForegroundActivities(foregroundActivities);
state.setCompletedAdjSeq(mAdjSeq);
state.setCurBoundByNonBgRestrictedApp(boundByNonBgRestricted);
// if curAdj or curProcState improved, then this process was promoted
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
|| state.getCurCapability() != prevCapability;
}
2.2.3 优先级的应用
优先级的应用是通过applyOomAdjLSP函数来实现的,大致流程如下
1. 判断是否要压缩cache进程
2. 更新新的adj到lmkd
3. 判断是否需要kill等待被杀的进程(进程是否在接收广播)
4. 根据curSchedGroup,更新priority,改变进程的CPU调度优先级
5. 更新进程冻结状态
6. 更新进程adj/procState/UsageStats等
7. 根据进程是否是bg限制模式,决定是否需要停止前台服务、进程是否可以被杀等
private boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now,
long nowElapsed, @OomAdjReason int oomAdjReson) {
boolean success = true;
final ProcessStateRecord state = app.mState;
final UidRecord uidRec = app.getUidRecord();
if (state.getCurRawAdj() != state.getSetRawAdj()) {//把curRawAdj赋值给setRawAdj
state.setSetRawAdj(state.getCurRawAdj());
}
int changes = 0;
if (state.getCurAdj() != state.getSetAdj()) {//判断是否要压缩cache进程
mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
}
if (state.getCurAdj() != state.getSetAdj()) {//把新的adj更新到lmkd
ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj());
state.setSetAdj(state.getCurAdj());
if (uidRec != null) {
uidRec.noteProcAdjChanged();
}
state.setVerifiedAdj(INVALID_ADJ);
}
final int curSchedGroup = state.getCurrentSchedulingGroup();
if (state.getSetSchedGroup() != curSchedGroup) {
int oldSchedGroup = state.getSetSchedGroup();
state.setSetSchedGroup(curSchedGroup);
if (app.getWaitingToKill() != null && app.mReceivers.numberOfCurReceivers() == 0
&& ActivityManager.isProcStateBackground(state.getSetProcState())) {//如果进程在等待被杀且没有在接收广播且进程状态是后台进程,则杀进程
app.killLocked(app.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_REMOVE_TASK, true);
success = false;
} else {
int processGroup;
switch (curSchedGroup) {
case SCHED_GROUP_BACKGROUND:
processGroup = THREAD_GROUP_BACKGROUND;
break;
case SCHED_GROUP_TOP_APP:
case SCHED_GROUP_TOP_APP_BOUND:
processGroup = THREAD_GROUP_TOP_APP;
break;
case SCHED_GROUP_RESTRICTED:
processGroup = THREAD_GROUP_RESTRICTED;
break;
default:
processGroup = THREAD_GROUP_DEFAULT;
break;
}
mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
0 /* unused */, app.getPid(), processGroup, app.processName));//调用Process.setProcessGroup,更新proc/%pid/cmdline节点信息
try {//根据curSchedGroup,更新priority
final int renderThreadTid = app.getRenderThreadTid();
if (curSchedGroup == SCHED_GROUP_TOP_APP) {
if (oldSchedGroup != SCHED_GROUP_TOP_APP) {//进程优先级上升到了topApp
app.getWindowProcessController().onTopProcChanged();
if (mService.mUseFifoUiScheduling) {//CPU调度模式是SCHED_FIFO
// Switch UI pipeline for app to SCHED_FIFO
state.setSavedPriority(Process.getThreadPriority(app.getPid()));
mService.scheduleAsFifoPriority(app.getPid(), true);
if (renderThreadTid != 0) {
mService.scheduleAsFifoPriority(renderThreadTid,
/* suppressLogs */true);
if (DEBUG_OOM_ADJ) {
Slog.d("UI_FIFO", "Set RenderThread (TID " +
renderThreadTid + ") to FIFO");
}
} else {
if (DEBUG_OOM_ADJ) {
Slog.d("UI_FIFO", "Not setting RenderThread TID");
}
}
} else {//进程调度模式不是SCHED_FIFO
// Boost priority for top app UI and render threads
setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
if (renderThreadTid != 0) {
try {
setThreadPriority(renderThreadTid,
THREAD_PRIORITY_TOP_APP_BOOST);
} catch (IllegalArgumentException e) {
// thread died, ignore
}
}
}
}
} else if (oldSchedGroup == SCHED_GROUP_TOP_APP
&& curSchedGroup != SCHED_GROUP_TOP_APP) {//进程优先级从topApp下降到了非topApp
app.getWindowProcessController().onTopProcChanged();
if (mService.mUseFifoUiScheduling) {//CPU调度模式是SCHED_FIFO
try {
// Reset UI pipeline to SCHED_OTHER
setThreadScheduler(app.getPid(), SCHED_OTHER, 0);
setThreadPriority(app.getPid(), state.getSavedPriority());
if (renderThreadTid != 0) {
setThreadScheduler(renderThreadTid,
SCHED_OTHER, 0);
}
} catch (IllegalArgumentException e) {
Slog.w(TAG,
"Failed to set scheduling policy, thread does not exist:\n"
+ e);
} catch (SecurityException e) {
Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
}
} else {//CPU调度模式不是SCHED_FIFO
// Reset priority for top app UI and render threads
setThreadPriority(app.getPid(), 0);
}
if (renderThreadTid != 0) {
setThreadPriority(renderThreadTid, THREAD_PRIORITY_DISPLAY);
}
}
} catch (Exception e) {
if (DEBUG_ALL) {
Slog.w(TAG, "Failed setting thread priority of " + app.getPid(), e);
}
}
}
}
if (state.hasRepForegroundActivities() != state.hasForegroundActivities()) {
state.setRepForegroundActivities(state.hasForegroundActivities());
changes |= ActivityManagerService.ProcessChangeItem.CHANGE_ACTIVITIES;
}
updateAppFreezeStateLSP(app, oomAdjReson);//更新进程冻结状态
if (state.getReportedProcState() != state.getCurProcState()) {//根据ReportedProcState更新procState
state.setReportedProcState(state.getCurProcState());
if (app.getThread() != null) {
try {
if (false) {
//RuntimeException h = new RuntimeException("here");
Slog.i(TAG, "Sending new process state " + state.getReportedProcState()
+ " to " + app /*, h*/);
}
app.getThread().setProcessState(state.getReportedProcState());
} catch (RemoteException e) {
}
}
}
boolean forceUpdatePssTime = false;
if (state.getSetProcState() == PROCESS_STATE_NONEXISTENT
|| ProcessList.procStatesDifferForMem(
state.getCurProcState(), state.getSetProcState())) {更新进程update时间
state.setLastStateTime(now);
forceUpdatePssTime = true;
}
synchronized (mService.mAppProfiler.mProfilerLock) {//更新进程状态
app.mProfile.updateProcState(app.mState);
mService.mAppProfiler.updateNextPssTimeLPf(
state.getCurProcState(), app.mProfile, now, forceUpdatePssTime);
}
if (state.getSetProcState() != state.getCurProcState()) {//进程状态和上一次有变化
boolean setImportant = state.getSetProcState() < PROCESS_STATE_SERVICE;
boolean curImportant = state.getCurProcState() < PROCESS_STATE_SERVICE;
if (setImportant && !curImportant) {//从重要进程变成非重要进程
state.setWhenUnimportant(now);
app.mProfile.mLastCpuTime.set(0);
}
maybeUpdateUsageStatsLSP(app, nowElapsed);//更新UsageStats(UsageStatsService是收集、聚合和保存应用程序使用数据的服务,这些数据可以被AppOps授权的应用查询)
maybeUpdateLastTopTime(state, now);//更新最后一次成为top应用的时间
state.setSetProcState(state.getCurProcState());//更新CurProcState到SetProcState
if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_HOME) {
state.setNotCachedSinceIdle(false);
}
if (!doingAll) {
synchronized (mService.mProcessStats.mLock) {
mService.setProcessTrackerStateLOSP(app,
mService.mProcessStats.getMemFactorLocked());
}
} else {
state.setProcStateChanged(true);
}
} else if (state.hasReportedInteraction()) {
final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange(
CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME);//static final int CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME = 2;
final long interactionThreshold = fgsInteractionChangeEnabled
? mConstants.USAGE_STATS_INTERACTION_INTERVAL_POST_S//private static final long DEFAULT_USAGE_STATS_INTERACTION_INTERVAL_POST_S = 10 * 60 * 1000;
: mConstants.USAGE_STATS_INTERACTION_INTERVAL_PRE_S;//private static final long DEFAULT_USAGE_STATS_INTERACTION_INTERVAL_PRE_S = 2 * 60 * 60 * 1000;
if ((nowElapsed - state.getInteractionEventTime()) > interactionThreshold) {
maybeUpdateUsageStatsLSP(app, nowElapsed);
}
} else {
final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange(
CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME);
final long interactionThreshold = fgsInteractionChangeEnabled
? mConstants.SERVICE_USAGE_INTERACTION_TIME_POST_S//private static final long DEFAULT_SERVICE_USAGE_INTERACTION_TIME_POST_S = 60 * 1000;
: mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S;//private static final long DEFAULT_SERVICE_USAGE_INTERACTION_TIME_PRE_S = 30 * 60 * 1000;
if ((nowElapsed - state.getFgInteractionTime()) > interactionThreshold) {
maybeUpdateUsageStatsLSP(app, nowElapsed);
}
}
if (state.getCurCapability() != state.getSetCapability()) {
state.setSetCapability(state.getCurCapability());
}
final boolean curBoundByNonBgRestrictedApp = state.isCurBoundByNonBgRestrictedApp();
if (curBoundByNonBgRestrictedApp != state.isSetBoundByNonBgRestrictedApp()) {
state.setSetBoundByNonBgRestrictedApp(curBoundByNonBgRestrictedApp);
if (!curBoundByNonBgRestrictedApp && state.isBackgroundRestricted()) {
mService.mHandler.post(() -> {
synchronized (mService) {
mService.mServices.stopAllForegroundServicesLocked(
app.uid, app.info.packageName);//停止所有前台服务
}
});
}
}
if (changes != 0) {
ActivityManagerService.ProcessChangeItem item =
mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid);
item.changes |= changes;
item.foregroundActivities = state.hasRepForegroundActivities();
}
if (state.isCached() && !state.shouldNotKillOnBgRestrictedAndIdle()) {//当处于UID空闲和bg限制模式时,它有资格被杀死,检查这些状态是否刚刚变化
if (!state.isSetCached() || state.isSetNoKillOnBgRestrictedAndIdle()) {//从非cache状态变成cache状态
state.setLastCanKillOnBgRestrictedAndIdleTime(nowElapsed);
if (mService.mDeterministicUidIdle
|| !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs);//延时60s发送IDLE_UIDS_MSG事件
}
}
}
state.setSetCached(state.isCached());
state.setSetNoKillOnBgRestrictedAndIdle(state.shouldNotKillOnBgRestrictedAndIdle());
return success;
}
三:小结
3.1 如何让特定进程尽可能不被lowmemorykiller杀?
Lowmemorykiller查杀是通过判断进程adj,那么只要保证进程拥有一个较低的adj值(例如启动一个前台Service),就可以减少进程被杀的可能。
3.2 如何让进程尽可能多的使用CPU?
可以通过Thread.setPriority()来自行设置线程的优先级,数值越低优先级越高,也就尽可能优先使用CPU。也可以在AndroidManifest.xml里设置android:priority