ActivityManagerService解读之进程管理updateOomAdjLocked方法

经过前面的ActivityManagerService解读之进程管理的介绍,我们知道AMS对进程的管理主要体现于更新LRU集合和更新进程OOM值两个方面。限于篇幅,前一篇没有对更新进程OOM的updateOomAdjLocked方法深入分析,只是介绍了原理。本篇将会详细分析updateOomAdjLocked方法。

代码分析

ActivityManagerService中updateOomAdjLocked有三种实现,主要分析无参的updateOomAdjLocked,由于其代码较多,我们将其分为几个部分逐一介绍:

1.执行oom更新之前一些基本参数的初始化重置

    @GuardedBy("this")
    final void updateOomAdjLocked() {
        final ActivityRecord TOP_ACT = resumedAppLocked(); //获取当前
        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
        final long now = SystemClock.uptimeMillis(); //系统开机不包括睡眠时间
        final long nowElapsed = SystemClock.elapsedRealtime(); //系统开机时间
        final long oldTime = now - ProcessList.MAX_EMPTY_TIME; //MAX_EMPTY_TIME是系统控制空进程能够保存的最大时间
        final int N = mLruProcesses.size(); //lru集合中进程的数量

        if (false) {
            RuntimeException e = new RuntimeException();
            e.fillInStackTrace();
            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
        }

        // Reset state in all uid records.
        for (int i=mActiveUids.size()-1; i>=0; i--) {
            final UidRecord uidRec = mActiveUids.valueAt(i);
            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                    "Starting update of " + uidRec);
            uidRec.reset();
        }

        mStackSupervisor.rankTaskLayersIfNeeded();

        mAdjSeq++; //记录执行该方法的次数
        mNewNumServiceProcs = 0;
        mNewNumAServiceProcs = 0;

        //系统默认CUR_MAX_EMPTY_PROCESSES=16,CUR_MAX_CACHED_PROCESSES=32
        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;

        //将adj在900~906之间的进程分为numSlots部分
        //900~906只有7个数字可用,但是adj位于该范围的进程数量往往远远不只
        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;//=3
        //N = mNumNonCachedProcs + mNumCachedHiddenProcs + numEmptyProcs
        //lru集合的大小 = 非缓存进程+缓存进程+空进程
        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
        if (numEmptyProcs > cachedProcessLimit) {
            numEmptyProcs = cachedProcessLimit;//保证空进程的数量在阀至内
        }
        mEmptyRemainingCapacity = emptyProcessLimit - numEmptyProcs;//空进程剩余的容量
        int emptyFactor = numEmptyProcs/numSlots;//空进程的计算因子
        if (emptyFactor < 1) emptyFactor = 1;//保证最小为1
        //缓存进程的计算因子
        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
        if (cachedFactor < 1) cachedFactor = 1;//保证最小为1
        int stepCached = 0;//代表每一个slot的深度,下同
        int stepEmpty = 0;
        int numCached = 0;//缓存进程的数量
        int numEmpty = 0;//空进程的数量
        int numTrimming = 0;//重要性低于home的后台进程数量
        //以上的一些计算因子,都是动态变化的,会随着对应的进程数量变化,决定着每一个slot中进程的step

        mNumNonCachedProcs = 0;//重设全局变量非缓存进程大小为0
        mNumCachedHiddenProcs = 0;//重设全局变量缓存进程大小为0

        // First update the OOM adjustment for each of the
        // application processes based on their current state.
        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;//在计算开始时,缓存进程的adj开始为900
        int nextCachedAdj = curCachedAdj+1;//下一个为901
        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;//在计算开始时,空进程的adj开始900
        int nextEmptyAdj = curEmptyAdj+2;//下一个为902

        boolean retryCycles = false;//标记再次进行循环

        // need to reset cycle state before calling computeOomAdjLocked because of service connections
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mLruProcesses.get(i);
            app.containsCycle = false;
        }

2.调用computeOomAdjLocked方法计算进程的oom

for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mLruProcesses.get(i);
            if (!app.killedByAm && app.thread != null) {
                app.procStateChanged = false;
                //计算app进程的adj
                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);

                // if any app encountered a cycle, we need to perform an additional loop later
                retryCycles |= app.containsCycle;

                //当执行完computeOomAdjLocked之后,对于缓存进程和空进程的app,如果发现还未进行adj设置,需要修改成正确的adj值
                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
                    switch (app.curProcState) {
                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
                            //处理缓存进程
                            // This process is a cached process holding activities...
                            // assign it the next cached value for that type, and then
                            // step that cached level.
                            app.curRawAdj = curCachedAdj;
                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
                                    + ")");
                            if (curCachedAdj != nextCachedAdj) {
                                stepCached++;//从这部分逻辑可以看出stepCached应该是表示一个深度
                                if (stepCached >= cachedFactor) {//cachedFactor用来表示每一个slot的最大深度
                                    stepCached = 0;//在一个slot内,他们的adj值是一样的
                                    curCachedAdj = nextCachedAdj;//下一个slot的adj值
                                    nextCachedAdj += 2;
                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
                                        //保证缓存进程和空进程的adj在900~906之间
                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
                                    }
                                }
                            }
                            break;
                        default://处理空进程
                            app.curRawAdj = curEmptyAdj;
                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
                                    + ")");
                            if (curEmptyAdj != nextEmptyAdj) {
                                stepEmpty++;
                                if (stepEmpty >= emptyFactor) {
                                    stepEmpty = 0;
                                    curEmptyAdj = nextEmptyAdj;
                                    nextEmptyAdj += 2;
                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
                                    }
                                }
                            }
                            break;
                    }
                }


            }
        }

        // Cycle strategy:循环策略
        // - Retry computing any process that has encountered a cycle.
        // - Continue retrying until no process was promoted.
        // - Iterate from least important to most important.
        int cycleCount = 0;
        while (retryCycles) {
            cycleCount++;
            retryCycles = false;

            for (int i=0; i<N; i++) {
                ProcessRecord app = mLruProcesses.get(i);
                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
                    app.adjSeq--;
                    app.completedAdjSeq--;
                }
            }

            for (int i=0; i<N; i++) {
                ProcessRecord app = mLruProcesses.get(i);
                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
                    if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
                        retryCycles = true;
                    }
                }
            }
        }

3.调用applyOomAdjLocked设置进程的oom

        //计算完毕之后,进行设置app的oom
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mLruProcesses.get(i);
            if (!app.killedByAm && app.thread != null) {
                applyOomAdjLocked(app, true, now, nowElapsed);

                // Count the number of process types.
                //计算各个类型进程的数量
                switch (app.curProcState) {
                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
                        mNumCachedHiddenProcs++;
                        numCached++;
                        //超过限制,杀进程回收资源
                        if (numCached > cachedProcessLimit) {
                            app.kill("cached #" + numCached, true);
                        }
                        break;
                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
                        //超过限制,杀进程回收资源
                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
                                && app.lastActivityTime < oldTime) {
                            app.kill("empty for "
                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
                                    / 1000) + "s", true);
                        } else {
                            numEmpty++;
                            if (numEmpty > emptyProcessLimit) {
                                app.kill("empty #" + numEmpty, true);
                            }
                        }
                        break;
                    default:
                        mNumNonCachedProcs++;
                        break;
                }

                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
                    // If this is an isolated process, there are no services
                    // running in it, and it's not a special process with a
                    // custom entry point, then the process is no longer
                    // needed.  We agressively kill these because we can by
                    // definition not re-use the same process again, and it is
                    // good to avoid having whatever code was running in them
                    // left sitting around after no longer needed.
                    app.kill("isolated not needed", true);
                } else {
                    // Keeping this process, update its uid.
                    final UidRecord uidRec = app.uidRecord;
                    if (uidRec != null) {
                        uidRec.ephemeral = app.info.isInstantApp();
                        if (uidRec.curProcState > app.curProcState) {
                            uidRec.curProcState = app.curProcState;
                        }
                        if (app.foregroundServices) {
                            uidRec.foregroundServices = true;
                        }
                    }
                }

                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
                        && !app.killedByAm) {
                    numTrimming++;//重要性低于Home的进程
                }
            }
        }

4.当执行完2和3之后,根据执行结果设置当前的内存等级,并根据当前的内存等级主动去回收内存

  •     public static final int ADJ_MEM_FACTOR_NORMAL = 0;//正常等级
  •     public static final int ADJ_MEM_FACTOR_MODERATE = 1;//中等等级
  •     public static final int ADJ_MEM_FACTOR_LOW = 2;//存在低内存
  •     public static final int ADJ_MEM_FACTOR_CRITICAL = 3;//严重低内存

一般内存等级修改会输出如下log

08-29 14:58:35.968  1339  1357 I am_mem_factor: [0,1]

 而对应的更细节的内存回收策略如下:

  • TRIM_MEMORY_COMPLETE = 80,
  • TRIM_MEMORY_MODERATE = 60,
  • TRIM_MEMORY_BACKGROUND = 40,
  • TRIM_MEMORY_UI_HIDDEN = 20,
  • TRIM_MEMORY_RUNNING_CRITICAL = 15,对应ADJ_MEM_FACTOR_CRITICAL
  • TRIM_MEMORY_RUNNING_LOW = 10,对应ADJ_MEM_FACTOR_LOW
  • TRIM_MEMORY_RUNNING_MODERATE = 5,对应ADJ_MEM_FACTOR_MODERATE和ADJ_MEM_FACTOR_NORMAL
        incrementProcStateSeqAndNotifyAppsLocked();

        mNumServiceProcs = mNewNumServiceProcs;

        // Now determine the memory trimming level of background processes.
        // Unfortunately we need to start at the back of the list to do this
        // properly.  We only do this if the number of background apps we
        // are managing to keep around is less than half the maximum we desire;
        // if we are keeping a good number around, we'll let them use whatever
        // memory they want.
        final int numCachedAndEmpty = numCached + numEmpty;//缓存进程和空进程的数量和
        int memFactor;//内存等级计算因子
        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {//缓存进程和空进程的数量都低于对应的规定阀值
            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {//同时他们的总和低于极端情况下的阀值
                //缓存进程和空进程的数量很少,并且总和也很少,此情况很极端
                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;//设置内存等级严重
            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
                //缓存进程和空进程的数量很少,但总和还行,我们认为此时的情况仅次于极端情况
                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
            } else {
                //缓存进程和空进程的数量很少,但总和不错,认为该情况为中级
                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
            }
        } else {//缓存进程和空进程的数量正常,该情况为正常
            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
        }
        // We always allow the memory level to go up (better).  We only allow it to go
        // down if we are in a state where that is allowed, *and* the total number of processes
        // has gone down since last time.
        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
        //memFactor取值在0-3之间,越大代表内存越紧张
        if (memFactor > mLastMemoryLevel) {
            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
                memFactor = mLastMemoryLevel;
                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
            }
        }
        //08-29 08:05:46.633  1339  2227 I am_mem_factor: [0,1],输出eventlog
        if (memFactor != mLastMemoryLevel) {
            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
        }
        mLastMemoryLevel = memFactor;
        mLastNumProcesses = mLruProcesses.size();
        //设置内存等级成功返回true
        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {//当前的内存等级不正常
            if (mLowRamStartTime == 0) {
                mLowRamStartTime = now;//记录时间
            }
            int step = 0;
            int fgTrimLevel;
            switch (memFactor) {
                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
                    break;
                case ProcessStats.ADJ_MEM_FACTOR_LOW:
                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
                    break;
                default:
                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
                    break;
            }
            int factor = numTrimming/3;//原理同上
            int minFactor = 2;
            if (mHomeProcess != null) minFactor++;
            if (mPreviousProcess != null) minFactor++;
            if (factor < minFactor) factor = minFactor;
            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;//默认设置最高的回收等级
            //这个循环很有意思,逆序遍历。因为LRU集合中越在后面的进程,优先级越高,代表用户使用的频率高
            //前面之前进程管理的文章中,我们介绍LRU集合的排序是依据进程中四大组件的状态,往往存在组件尤其是activity的情况
            //该进程在LRU集合的位置就越靠后,也就意味着其占有的内存也较多,因此他就越需要进行内存回收。
            for (int i=N-1; i>=0; i--) {
                ProcessRecord app = mLruProcesses.get(i);
                if (allChanged || app.procStateChanged) {
                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
                    app.procStateChanged = false;
                }
                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
                        && !app.killedByAm) {//procstate >= 13
                    //进程优先级大于Home进程,也可以认为adj>=600,也就是相对于用户重要程度低于Home进程
                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
                        //当前进程的内存回收等级小于当前的内存回收等级,说明之前内存情况较好,现在需要进行内存回收
                        try {
                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                    "Trimming memory of " + app.processName + " to " + curLevel);
                            app.thread.scheduleTrimMemory(curLevel);
                        } catch (RemoteException e) {
                        }
                        if (false) {
                            // For now we won't do this; our memory trimming seems
                            // to be good enough at this point that destroying
                            // activities causes more harm than good.
                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
                                    && app != mHomeProcess && app != mPreviousProcess) {
                                // Need to do this on its own message because the stack may not
                                // be in a consistent state at this point.
                                // For these apps we will also finish their activities
                                // to help them free memory.
                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
                            }
                        }
                    }
                    app.trimMemoryLevel = curLevel;
                    step++;
                    if (step >= factor) {//回收一定程度(即处理完一个slot之后),按需要降低内存回收等级
                        step = 0;
                        switch (curLevel) {
                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
                                break;
                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
                                break;
                        }
                    }
                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
                        && !app.killedByAm) {//procstate == 12
                    //处理重量级进程
                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
                            && app.thread != null) {
                        try {
                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                    "Trimming memory of heavy-weight " + app.processName
                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
                            app.thread.scheduleTrimMemory(
                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
                        } catch (RemoteException e) {
                        }
                    }
                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
                } else {//procstate < 12
                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
                            || app.systemNoUi) && app.pendingUiClean) {
                        // If this application is now in the background and it
                        // had done UI, then give it the special trim level to
                        // have it free UI resources.
                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
                        if (app.trimMemoryLevel < level && app.thread != null) {
                            try {
                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                        "Trimming memory of bg-ui " + app.processName
                                        + " to " + level);
                                app.thread.scheduleTrimMemory(level);
                            } catch (RemoteException e) {
                            }
                        }
                        app.pendingUiClean = false;
                    }
                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
                        try {
                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                    "Trimming memory of fg " + app.processName
                                    + " to " + fgTrimLevel);
                            app.thread.scheduleTrimMemory(fgTrimLevel);
                        } catch (RemoteException e) {
                        }
                    }
                    app.trimMemoryLevel = fgTrimLevel;
                }
            }
        } else {//内存等级因子正常值
            if (mLowRamStartTime != 0) {
                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
                mLowRamStartTime = 0;
            }
            for (int i=N-1; i>=0; i--) {
                ProcessRecord app = mLruProcesses.get(i);
                if (allChanged || app.procStateChanged) {
                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
                    app.procStateChanged = false;
                }
                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
                        || app.systemNoUi) && app.pendingUiClean) {
                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                            && app.thread != null) {
                        try {
                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
                                    "Trimming memory of ui hidden " + app.processName
                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
                            app.thread.scheduleTrimMemory(
                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
                        } catch (RemoteException e) {
                        }
                    }
                    app.pendingUiClean = false;
                }
                app.trimMemoryLevel = 0;
            }
        }

5.当执行完234之后,重新计算进程的PSS值,外加一些额外的结束工作

Item

全称

含义

等价

USS

Unique Set Size

物理内存

进程独占的内存

PSS

Proportional Set Size

物理内存

PSS= USS+ 按比例包含共享库

RSS

Resident Set Size

物理内存

RSS= USS+ 包含共享库

VSS

Virtual Set Size

虚拟内存

VSS= RSS+ 未分配实际物理内存

SystemUI进程来说:
VSS:通常不关注
RSS:
SystemUI进程实际占用的物理内存加上所有(其他进程,比如Settings进程...)共享库占用的内存
PSS:
SystemUI进程实际占用的物理内存加上自己(SystemUI进程)的共享库占用的内存
USS:
SystemUI进程实际占用的物理内存
一般来说内存占用大小有如下规律:
VSS >= RSS >= PSS >= USS

        if (mAlwaysFinishActivities) {
            // Need to do this on its own message because the stack may not
            // be in a consistent state at this point.
            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
        }

        if (allChanged) {
            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
        }

        ArrayList<UidRecord> becameIdle = null;

        // Update from any uid changes.
        if (mLocalPowerManager != null) {
            mLocalPowerManager.startUidChanges();
        }
        for (int i=mActiveUids.size()-1; i>=0; i--) {
            final UidRecord uidRec = mActiveUids.valueAt(i);
            int uidChange = UidRecord.CHANGE_PROCSTATE;
            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
                    && (uidRec.setProcState != uidRec.curProcState
                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
                        + " to " + uidRec.curWhitelist);
                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
                        && !uidRec.curWhitelist) {
                    // UID is now in the background (and not on the temp whitelist).  Was it
                    // previously in the foreground (or on the temp whitelist)?
                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
                            || uidRec.setWhitelist) {
                        uidRec.lastBackgroundTime = nowElapsed;
                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
                            // Note: the background settle time is in elapsed realtime, while
                            // the handler time base is uptime.  All this means is that we may
                            // stop background uids later than we had intended, but that only
                            // happens because the device was sleeping so we are okay anyway.
                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
                                    mConstants.BACKGROUND_SETTLE_TIME);
                        }
                    }
                    if (uidRec.idle && !uidRec.setIdle) {
                        uidChange = UidRecord.CHANGE_IDLE;
                        if (becameIdle == null) {
                            becameIdle = new ArrayList<>();
                        }
                        becameIdle.add(uidRec);
                    }
                } else {
                    if (uidRec.idle) {
                        uidChange = UidRecord.CHANGE_ACTIVE;
                        EventLogTags.writeAmUidActive(uidRec.uid);
                        uidRec.idle = false;
                    }
                    uidRec.lastBackgroundTime = 0;
                }
                final boolean wasCached = uidRec.setProcState
                        > ActivityManager.PROCESS_STATE_RECEIVER;
                final boolean isCached = uidRec.curProcState
                        > ActivityManager.PROCESS_STATE_RECEIVER;
                if (wasCached != isCached ||
                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
                }
                uidRec.setProcState = uidRec.curProcState;
                uidRec.setWhitelist = uidRec.curWhitelist;
                uidRec.setIdle = uidRec.idle;
                enqueueUidChangeLocked(uidRec, -1, uidChange);
                noteUidProcessState(uidRec.uid, uidRec.curProcState);
                if (uidRec.foregroundServices) {
                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
                }
            }
        }
        if (mLocalPowerManager != null) {
            mLocalPowerManager.finishUidChanges();
        }

        if (becameIdle != null) {
            // If we have any new uids that became idle this time, we need to make sure
            // they aren't left with running services.
            for (int i = becameIdle.size() - 1; i >= 0; i--) {
                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
            }
        }

        if (mProcessStats.shouldWriteNowLocked(now)) {
            mHandler.post(new Runnable() {
                @Override public void run() {
                    synchronized (ActivityManagerService.this) {
                        mProcessStats.writeStateAsyncLocked();
                    }
                }
            });
        }

        if (DEBUG_OOM_ADJ) {
            final long duration = SystemClock.uptimeMillis() - now;
            if (false) {
                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
                        new RuntimeException("here").fillInStackTrace());
            } else {
                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
            }
        }
    }

updateOomAdjLocked方法总算是撸完了,其中2中提到的computeOomAdjLocked和3中的applyOomAdjLocked我们并未详细介绍,后续还是会以文章的形式分享,感谢阅读,渴求指正。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值