Android进程管理-进程优先级(AndroidU)

目录

一:概念

1.1 进程

1.2 进程优先级

1.2.1 adj

1.2.2 Schedule Group

1.2.3 ProcessState

二:优先级的更新

2.1 优先级更新的依据

2.2 更新优先级

2.2.1 优先级更新时机

2.2.2 优先级的计算

2.2.3 优先级的应用


一:概念

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值