经过前面的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我们并未详细介绍,后续还是会以文章的形式分享,感谢阅读,渴求指正。