Android進程調度之adj算法
一、概述
提到進程調度,可能大家首先想到的是cpu調度算法,進程優先級這些概念,本文并不打算介紹這些內容,而是介紹Android framework層中承載activity/service/contentprovider/broadcastrecevier的進程是如何根據組件運行狀態而動態調節進程自身的狀態。進程有兩個比較重要的狀態值,即adj(定義在 ProcessList.java )和procState(定義在 ActivityManager.java )。
1.1 核心方法
調整進程的adj的3大護法:
- updateOomAdjLocked :更新adj,當目標進程為空,或者被殺則返回false;否則返回true;
- computeOomAdjLocked :計算adj,返回計算后RawAdj值;
- applyOomAdjLocked :應用adj,當需要殺掉目標進程則返回false;否則返回true。
前面提到調整adj的3大護法,最為常見的方法便是computeOomAdjLocked,這也是其他各個方法在需要更新adj時會調用的方法,該方法有3個不同參數的同名方法,定義如下:
無參方法:updateOomAdjLocked()
一參方法:updateOomAdjLocked(ProcessRecord app)
三參方法:updateOomAdjLocked(ProcessRecord app, int cachedAdj,
ProcessRecord TOP_APP, boolean doingAll, long now)
updateOomAdjLocked的實現過程中依次會 computeOomAdjLocked 和 applyOomAdjLocked 。
1.2 使用場景
到底哪些地方會需要updateOomAdjLocked呢,其實很多地方,下面列舉常見場景:
- Activity的start/resume/finish;
- Service的start/bind/unbind;
- broadcast的分發/處理;
- contentprovider的發布/移除/獲取;
- 進程的kill/attach等。
二、ADJ算法
ADJ算法,其核心也就是updateOomAdjLocked方法。
2.1 一參updateOomAdjLocked
[-> ActivityManagerService.java]
final boolean updateOomAdjLocked(ProcessRecord app) {
//獲取棧頂的Activity
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
final boolean wasCached = app.cached;
mAdjSeq++;
//確保cachedAdj>=9
final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
//執行三參updateOomAdjLocked【見小節2.2】
boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
SystemClock.uptimeMillis());
//當app cached狀態改變,或者curRawAdj=16,則執行無參數updateOomAdjLocked【見小節2.3】
if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
updateOomAdjLocked();
}
return success;
}</code></pre>
該方法:
- 執行 三參updateOomAdjLocked ;
- 當app經過更新adj操作后,其cached狀態改變(包括由cached變成非cached,或者非cached變成cached),或者curRawAdj=16,則執行``無參updateOomAdjLocked`;
2.2 三參updateOomAdjLocked
private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
ProcessRecord TOP_APP, boolean doingAll, long now) {
if (app.thread == null) {
return false;
}
//【見小節2.4】
computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
//【見小節2.5】
return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
}</code></pre>
該方法是private方法,只提供給一參和無參的同名方法調用,系統中并沒有其他地方調用。
2.3 無參updateOomAdjLocked
2.3.1 涉及的部分參數
[-> ProcessList.java]
- 空進程存活時長: MAX_EMPTY_TIME = 30min
- (緩存+空)進程個數上限: MAX_CACHED_APPS = SystemProperties.getInt(“sys.fw.bg_apps_limit”,32) = 32(默認);
- 空進程個數上限: MAX_EMPTY_APPS = computeEmptyProcessLimit(MAX_CACHED_APPS) = MAX_CACHED_APPS/2 = 16;
- trim空進程個數上限: TRIM_EMPTY_APPS = computeTrimEmptyApps() = MAX_EMPTY_APPS/2 = 8;
- trim緩存進程個數上限: TRIM_CACHED_APPS = computeTrimCachedApps() = MAX_CACHED_APPS-MAX_EMPTY_APPS)/3 = 5;
- TRIM_CRITICAL_THRESHOLD = 3;
[-> AMS.java]
- mBServiceAppThreshold = SystemProperties.getInt(“ro.sys.fw.bservice_limit”, 5);
- mMinBServiceAgingTime =SystemProperties.getInt(“ro.sys.fw.bservice_age”, 5000);
- mProcessLimit = ProcessList.MAX_CACHED_APPS
- mProcessLimit = emptyProcessLimit(空進程上限) + cachedProcessLimit(緩存進程上限)
- oldTime = now - ProcessList.MAX_EMPTY_TIME;
- LRU進程隊列長度 = numEmptyProcs(空進程數) + mNumCachedHiddenProcs(cached進程) + mNumNonCachedProcs(非cached進程)
- emptyFactor = numEmptyProcs/3, 且大于等于1
- cachedFactor = mNumCachedHiddenProcs/3, 且大于等于1
2.3.2 代碼
final void updateOomAdjLocked() {
//獲取棧頂的Activity
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;
final int N = mLruProcesses.size();
//重置所有uid記錄,把curProcState設置成16(空進程)
for (int i=mActiveUids.size()-1; i>=0; i--) {
final UidRecord uidRec = mActiveUids.valueAt(i);
uidRec.reset();
}
mAdjSeq++;
mNewNumServiceProcs = 0;
mNewNumAServiceProcs = 0;
final int emptyProcessLimit;
final int cachedProcessLimit;
// mProcessLimit默認值等于32,通過開發者選擇可設置,或者廠商會自行調整
if (mProcessLimit <= 0) {
emptyProcessLimit = cachedProcessLimit = 0;
} else if (mProcessLimit == 1) {
emptyProcessLimit = 1;
cachedProcessLimit = 0;
} else {
//則emptyProcessLimit = 16, cachedProcessLimit = 16
emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
cachedProcessLimit = mProcessLimit - emptyProcessLimit;
}
//經過計算得 numSlots =3
int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
- ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
//確保空進程個數不大于cached進程數
if (numEmptyProcs > cachedProcessLimit) {
numEmptyProcs = cachedProcessLimit;
}
int emptyFactor = numEmptyProcs/numSlots;
if (emptyFactor < 1) emptyFactor = 1;
int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
if (cachedFactor < 1) cachedFactor = 1;
int stepCached = 0;
int stepEmpty = 0;
int numCached = 0;
int numEmpty = 0;
int numTrimming = 0;
mNumNonCachedProcs = 0;
mNumCachedHiddenProcs = 0;
//更新所有進程狀態(基于當前狀態)
int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextCachedAdj = curCachedAdj+1;
int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
ProcessRecord selectedAppRecord = null;
long serviceLastActivity = 0;
int numBServices = 0;
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (mEnableBServicePropagation && app.serviceb
&& (app.curAdj == ProcessList.SERVICE_B_ADJ)) {
numBServices++;
for (int s = app.services.size() - 1; s >= 0; s--) {
ServiceRecord sr = app.services.valueAt(s);
//上次活躍時間距離現在小于5s,則不會遷移到BService
if (SystemClock.uptimeMillis() - sr.lastActivity
< mMinBServiceAgingTime) {
continue;
}
if (serviceLastActivity == 0) {
serviceLastActivity = sr.lastActivity;
selectedAppRecord = app;
//記錄service上次活動時間最長的那個app
} else if (sr.lastActivity < serviceLastActivity) {
serviceLastActivity = sr.lastActivity;
selectedAppRecord = app;
}
}
}
if (!app.killedByAm && app.thread != null) {
app.procStateChanged = false;
//計算app的adj值【見小節2.4】
computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
//當進程未分配adj的情況下,更新adj(cached和empty算法是相同的)
if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
switch (app.curProcState) {
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
//當進程procState=14或15,則設置adj=9;
app.curRawAdj = curCachedAdj;
app.curAdj = app.modifyRawOomAdj(curCachedAdj);
//當前cacheadj不等于下一次cachedadj時
if (curCachedAdj != nextCachedAdj) {
stepCached++;
//當stepCached大于cachedFactor,則將nextCachedAdj賦值給curCachedAdj,并且nextCachedAdj加2,nextCachedAdj最大等于15;
if (stepCached >= cachedFactor) {
stepCached = 0;
curCachedAdj = nextCachedAdj;
nextCachedAdj += 2;
if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
}
}
break;
default:
app.curRawAdj = curEmptyAdj;
app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
//更新curCachedAdj值
if (curEmptyAdj != nextEmptyAdj) {
stepEmpty++;
//當stepEmpty大于emptyFactor,則將nextEmptyAdj賦值給curEmptyAdj,并且nextEmptyAdj加2,nextEmptyAdj最大等于15;
if (stepEmpty >= emptyFactor) {
stepEmpty = 0;
curEmptyAdj = nextEmptyAdj;
nextEmptyAdj += 2;
if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
}
}
break;
}
}
//【見小節2.5】
applyOomAdjLocked(app, true, now, nowElapsed);
//根據當前進程procState狀態來決策
switch (app.curProcState) {
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
mNumCachedHiddenProcs++;
numCached++;
// 當cached進程超過上限(cachedProcessLimit),則殺掉該進程
if (numCached > cachedProcessLimit) {
app.kill("cached #" + numCached, true);
}
break;
case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
// 當空進程超過上限(TRIM_EMPTY_APPS),且空閑時間超過30分鐘,則殺掉該進程
if (numEmpty > ProcessList.TRIM_EMPTY_APPS
&& app.lastActivityTime < oldTime) {
app.kill("empty for "
+ ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
/ 1000) + "s", true);
} else {
// 當空進程超過上限(emptyProcessLimit),則殺掉該進程
numEmpty++;
if (numEmpty > emptyProcessLimit) {
if (!CT_PROTECTED_PROCESS.equals(app.processName))
app.kill("empty #" + numEmpty, true);
}
}
break;
default:
mNumNonCachedProcs++;
break;
}
if (app.isolated && app.services.size() <= 0) {
//沒有services運行的孤立進程,則直接殺掉
app.kill("isolated not needed", true);
} else {
final UidRecord uidRec = app.uidRecord;
if (uidRec != null && uidRec.curProcState > app.curProcState) {
uidRec.curProcState = app.curProcState;
}
}
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
&& !app.killedByAm) {
numTrimming++;
}
}
}
//當BServices個數超過上限(mBServiceAppThreshold),則
if ((numBServices > mBServiceAppThreshold) && (true == mAllowLowerMemLevel)
&& (selectedAppRecord != null)) {
ProcessList.setOomAdj(selectedAppRecord.pid, selectedAppRecord.info.uid,
ProcessList.CACHED_APP_MAX_ADJ);
selectedAppRecord.setAdj = selectedAppRecord.curAdj;
}
mNumServiceProcs = mNewNumServiceProcs;
//根據CachedAndEmpty個數來調整內存因子memFactor
final int numCachedAndEmpty = numCached + numEmpty;
int memFactor;
if (numCached <= ProcessList.TRIM_CACHED_APPS
&& numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
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;
}
if (memFactor > mLastMemoryLevel) {
if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
memFactor = mLastMemoryLevel;
}
}
mLastMemoryLevel = memFactor;
mLastNumProcesses = mLruProcesses.size();
boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
final int trackerMemFactor = mProcessStats.getMemFactorLocked();
//當內存因子不是普通0級別的情況下
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;
//TRIM_MEMORY_COMPLETE:該進程處于LRU隊列的尾部,當進程不足則會殺掉該進程
int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (allChanged || app.procStateChanged) {
setProcessTrackerStateLocked(app, trackerMemFactor, now);
app.procStateChanged = false;
}
//當curProcState > 12且沒有被am殺掉的情況;
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
&& !app.killedByAm) {
if (app.trimMemoryLevel < curLevel && app.thread != null) {
//調度app執行trim memory的操作
app.thread.scheduleTrimMemory(curLevel);
}
app.trimMemoryLevel = curLevel;
step++;
if (step >= factor) {
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) {
if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
&& app.thread != null) {
app.thread.scheduleTrimMemory(
ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
}
app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
} else {
if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
|| app.systemNoUi) && app.pendingUiClean) {
final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
if (app.trimMemoryLevel < level && app.thread != null) {
app.thread.scheduleTrimMemory(level);
}
app.pendingUiClean = false;
}
if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
app.thread.scheduleTrimMemory(fgTrimLevel);
}
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) {
app.thread.scheduleTrimMemory(
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
}
app.pendingUiClean = false;
}
app.trimMemoryLevel = 0;
}
}
//是否finish activity
if (mAlwaysFinishActivities) {
mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
}
if (allChanged) {
requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
}
...
}</code></pre>
2.3.3 updateOomAdjLocked小節
updateOomAdjLocked過程比較復雜,主要分為更新adj(滿足條件則殺進程)和根據memFactor來調度執行TrimMemory操作;
第一部分:更新adj(滿足條件則殺進程)
- 遍歷mLruProcesses進程
- 當進程未分配adj的情況
- 當進程procState=14或15,則設置 adj=curCachedAdj(初始化=9) ;
- 當curCachedAdj != nextCachedAdj,且stepCached大于cachedFactor時 則 curCachedAdj = nextCachedAdj ,(nextCachedAdj加2,nextCachedAdj上限為15);
</li>
- 否則,則設置 adj=curEmptyAdj(初始化=9) ;
- 當curEmptyAdj != nextEmptyAdj,且stepEmpty大于EmptyFactor時 則 curEmptyAdj = nextEmptyAdj ,(nextEmptyAdj加2,nextEmptyAdj上限為15);
</ul> </li>
</ul> </li>
- 根據當前進程procState狀態來決策:
- 當curProcState=14或15,且cached進程超過上限(cachedProcessLimit=32),則殺掉該進程
- 當curProcState=16的前提下:
- 當空進程超過上限(TRIM_EMPTY_APPS=8),且空閑時間超過30分鐘,則殺掉該進程
- 否則,當空進程超過上限(emptyProcessLimit=16),則殺掉該進程
</ul> </li>
</ul> </li>
- 沒有services運行的孤立進程,則殺掉該進程;
</ul> </li>
</ul>
第二部分:根據memFactor來調度執行TrimMemory操作;
- 根據CachedAndEmpty個數來調整內存因子memFactor(值越大,級別越高):
- 當CachedAndEmpty < 3,則memFactor=3;
- 當CachedAndEmpty < 5,則memFactor=2;
- 當CachedAndEmpty >=5,且numCached<=5,numEmpty<=8,則memFactor=1;
- 當numCached>5 或numEmpty>8,則memFactor=0;
</li>
- 當內存因子不是普通0級別的情況下,根據memFactor來調整前臺trim級別(fgTrimLevel):
- 當memFactor=3,則fgTrimLevel=TRIM_MEMORY_RUNNING_CRITICAL;
- 當memFactor=2,則fgTrimLevel=TRIM_MEMORY_RUNNING_LOW;
-
否則(其實就是memFactor=1),則fgTrimLevel=TRIM_MEMORY_RUNNING_MODERATE
- 再遍歷mLruProcesses隊列進程:
- 當curProcState > 12且沒有被am殺掉,則執行TrimMemory操作;
- 否則,當curProcState = 9 且trimMemoryLevel<TRIM_MEMORY_BACKGROUND,則執行TrimMemory操作;
- 否則,當curProcState > 7, 且pendingUiClean =true時
- 當trimMemoryLevel<TRIM_MEMORY_UI_HIDDEN,則執行TrimMemory操作;
- 當trimMemoryLevel<fgTrimLevel,則執行TrimMemory操作;
</ul> </li>
</ul> </li>
</ul> </li>
- 當內存因子等于0的情況下,遍歷mLruProcesses隊列進程:
- 當curProcState >=7, 且pendingUiClean =true時,
- 當trimMemoryLevel< TRIM_MEMORY_UI_HIDDEN,則執行TrimMemory操作;
</ul> </li>
</ul> </li>
</ul>
2.4 computeOomAdjLocked
private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
boolean doingAll, long now);
該方法比較長,下面分幾個部分來展開說明: (adj和procState的取值原則是以優先級高為主)
2.4.1 進程為空的情況
if (mAdjSeq == app.adjSeq) {
//已經調整完成
return app.curRawAdj;
}
// 當進程對象為空時,則設置curProcState=16, curAdj=curRawAdj=15
if (app.thread == null) {
app.adjSeq = mAdjSeq;
app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
}
//app中包含的activity個數
final int activitiesSize = app.activities.size();</code></pre>
2.4.2 當maxAdj<=0情況
當maxAdj <=0的情況,也就意味這不允許app將其adj調整到低于前臺app的優先級別。
if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
app.adjType = "fixed";
app.adjSeq = mAdjSeq;
app.curRawAdj = app.maxAdj;
app.foregroundActivities = false;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
app.systemNoUi = true;
//頂部的activity就是當前app,則代表正處于展現UI
if (app == TOP_APP) {
app.systemNoUi = false;
} else if (activitiesSize > 0) {
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.visible) {
app.systemNoUi = false;
}
}
}
if (!app.systemNoUi) {
app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
}
return (app.curAdj=app.maxAdj);
}</code></pre>
該過程執行后將直接返回
- curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
- curAdj = app.maxAdj
2.4.3 計算adj和procState
if (app == TOP_APP) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "top-activity";
foregroundActivities = true;
procState = PROCESS_STATE_TOP;
if(app == mHomeProcess) {
mHomeKilled = false;
mHomeProcessName = mHomeProcess.processName;
}
} else if (app.instrumentationClass != null) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "instrumentation";
procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
} else if ((queue = isReceivingBroadcast(app)) != null) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = (queue == mFgBroadcastQueue)
? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.adjType = "broadcast";
procState = ActivityManager.PROCESS_STATE_RECEIVER;
} else if (app.executingServices.size() > 0) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = app.execServicesFg ?
Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.adjType = "exec-service";
procState = ActivityManager.PROCESS_STATE_SERVICE;
} else {
//top app; isReceivingBroadcast;executingServices;除此之外則為PROCESS_STATE_CACHED_EMPTY【】
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
adj = cachedAdj;
procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
app.cached = true;
app.empty = true;
app.adjType = "cch-empty";
if (mHomeKilled && app.processName.equals(mHomeProcessName)) {
adj = ProcessList.PERSISTENT_PROC_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.cached = false;
app.empty = false;
app.adjType = "top-activity";
}
}</code></pre>
Case
adj
procState
當app是當前展示的app
adj=0
procState=2
當instrumentation不為空時
adj=0
procState=4
當進程存在正在接收的broadcastrecevier
adj=0
procState=11
當進程存在正在執行的service
adj=0
procState=10
以上條件都不符合
adj=cachedAdj
procState=16
其中cachedAdj大于等于9,該值來源于computeOomAdjLocked輸入參數
2.4.4 非前臺activity的情況
if (!foregroundActivities && activitiesSize > 0) {
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.app != app) {
continue;
}
當activity可見, 則adj=1,procState=2
if (r.visible) {
if (adj > ProcessList.VISIBLE_APP_ADJ) {
adj = ProcessList.VISIBLE_APP_ADJ;
app.adjType = "visible";
}
if (procState > PROCESS_STATE_TOP) {
procState = PROCESS_STATE_TOP;
}
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.cached = false;
app.empty = false;
foregroundActivities = true;
break;
當activity正在暫停或者已經暫停, 則adj=2,procState=2
} else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.adjType = "pausing";
}
if (procState > PROCESS_STATE_TOP) {
procState = PROCESS_STATE_TOP;
}
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.cached = false;
app.empty = false;
foregroundActivities = true;
當activity正在停止, 則adj=2,procState=13(activity尚未finish)
} else if (r.state == ActivityState.STOPPING) {
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.adjType = "stopping";
}
if (!r.finishing) {
if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
}
}
app.cached = false;
app.empty = false;
foregroundActivities = true;
否則procState=14
} else {
if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
app.adjType = "cch-act";
}
}
}
}</code></pre>
對于進程中的activity處于非前臺情況
- 當activity可見, 則adj=1,procState=2;
- 當activity正在暫停或者已經暫停, 則adj=2,procState=2;
- 當activity正在停止, 則adj=2,procState=13(且activity尚未finish);
- 以上都不滿足,否則procState=14
2.4.5 adj > 2的情況
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
當存在前臺service時,則adj=2, procState=4;
if (app.foregroundServices) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
app.cached = false;
app.adjType = "fg-service";
schedGroup = Process.THREAD_GROUP_DEFAULT;
當強制前臺時,則adj=2, procState=6;
} else if (app.forcingToForeground != null) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
app.cached = false;
app.adjType = "force-fg";
app.adjSource = app.forcingToForeground;
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
}
當adj > 2的情況的前提下:
- 當存在前臺service時,則adj=2, procState=4;
- 當強制前臺時,則adj=2, procState=6;
2.4.6 HeavyWeightProces情況
if (app == mHeavyWeightProcess) {
if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.cached = false;
app.adjType = "heavy";
}
if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
}
}
當進程為HeavyWeightProcess,則adj=4, procState=9;
2.4.7 HomeProcess情況
if (app == mHomeProcess) {
if (adj > ProcessList.HOME_APP_ADJ) {
adj = ProcessList.HOME_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.cached = false;
app.adjType = "home";
}
if (procState > ActivityManager.PROCESS_STATE_HOME) {
procState = ActivityManager.PROCESS_STATE_HOME;
}
}
當進程為HomeProcess情況,則adj=6, procState=12;
2.4.8 PreviousProcess情況
if (app == mPreviousProcess && app.activities.size() > 0) {
if (adj > ProcessList.PREVIOUS_APP_ADJ) {
adj = ProcessList.PREVIOUS_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.cached = false;
app.adjType = "previous";
}
if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
}
}
當進程為PreviousProcess情況,則adj=7, procState=13;
2.4.9 備份進程情況
if (mBackupTarget != null && app == mBackupTarget.app) {
if (adj > ProcessList.BACKUP_APP_ADJ) {
adj = ProcessList.BACKUP_APP_ADJ;
if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
}
app.adjType = "backup";
app.cached = false;
}
if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
procState = ActivityManager.PROCESS_STATE_BACKUP;
}
}
對于備份進程的情況,則adj=3, procState=7或8
2.4.10 Service情況
//是否顯示在最頂部
boolean mayBeTop = false;
for (int is = app.services.size()-1;
is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
|| procState > ActivityManager.PROCESS_STATE_TOP);
is--) {
//當adj>0 或 schedGroup為后臺線程組 或procState>2時執行
ServiceRecord s = app.services.valueAt(is);
if (s.startRequested) {
app.hasStartedServices = true;
//當service已啟動,則procState<=10;
if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
procState = ActivityManager.PROCESS_STATE_SERVICE;
}
if (app.hasShownUi && app != mHomeProcess) {
if (adj > ProcessList.SERVICE_ADJ) {
app.adjType = "cch-started-ui-services";
}
} else {
if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
//當service在30分鐘內活動過,則adj=5;
if (adj > ProcessList.SERVICE_ADJ) {
adj = ProcessList.SERVICE_ADJ;
app.adjType = "started-services";
app.cached = false;
}
}
if (adj > ProcessList.SERVICE_ADJ) {
app.adjType = "cch-started-services";
}
}
}
for (int conni = s.connections.size()-1;
conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
|| procState > ActivityManager.PROCESS_STATE_TOP);
conni--) {
// 獲取service所綁定的connections
ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
for (int i = 0;
i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
|| procState > ActivityManager.PROCESS_STATE_TOP);
i++) {
ConnectionRecord cr = clist.get(i);
//當client與當前app同一個進程,則continue;
if (cr.binding.client == app) {
continue;
}
if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
ProcessRecord client = cr.binding.client;
//計算connections所對應的client進程的adj
int clientAdj = computeOomAdjLocked(client, cachedAdj,
TOP_APP, doingAll, now);
int clientProcState = client.curProcState;
//當client進程的ProcState >=cache,則設置為空進程
if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
}
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
//當進程存在顯示的ui,則將當前進程的adj和ProcState值賦予給client進程
if (app.hasShownUi && app != mHomeProcess) {
if (adj > clientAdj) {
adjType = "cch-bound-ui-services";
}
app.cached = false;
clientAdj = adj;
clientProcState = procState;
} else {
//當不存在顯示的ui,且service上次活動時間距離現在超過30分鐘,則只將當前進程的adj值賦予給client進程
if (now >= (s.lastActivity
+ ActiveServices.MAX_SERVICE_INACTIVITY)) {
if (adj > clientAdj) {
adjType = "cch-bound-services";
}
clientAdj = adj;
}
}
}
//當前進程adj > client進程adj的情況
if (adj > clientAdj) {
if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adjType = "cch-bound-ui-services";
} else {
//當service進程比較重要時,設置adj >= -11
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
|Context.BIND_IMPORTANT)) != 0) {
adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
//當client進程adj<2,且當前進程adj>2時,設置adj=2;
} else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
&& clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
&& adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
//當client進程adj>1時,則設置adj = clientAdj
} else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
adj = clientAdj;
} else {
//否則,設置adj <= 1
if (adj > ProcessList.VISIBLE_APP_ADJ) {
adj = ProcessList.VISIBLE_APP_ADJ;
}
}
//當client進程不是cache進程,則當前進程也設置為非cache進程
if (!client.cached) {
app.cached = false;
}
adjType = "service";
}
}
//當綁定的是前臺進程的情況
if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
//當client進程狀態為前臺時,則設置mayBeTop=true,并設置client進程procState=16
if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
mayBeTop = true;
clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
//當client進程狀態 < 2的前提下:若綁定前臺service,則clientProcState=3;否則clientProcState=6
} else {
if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
clientProcState =
ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
} else if (mWakefulness
== PowerManagerInternal.WAKEFULNESS_AWAKE &&
(cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
!= 0) {
clientProcState =
ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
} else {
clientProcState =
ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
}
}
}
//當connections并沒有綁定前臺service時,則clientProcState >= 7
} else {
if (clientProcState <
ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
clientProcState =
ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
}
}
//保證當前進程procState不會必client進程的procState大
if (procState > clientProcState) {
procState = clientProcState;
}
if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
&& (cr.flags&Context.BIND_SHOWING_UI) != 0) {
app.pendingUiClean = true;
}
if (adjType != null) {
app.adjType = adjType;
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE;
app.adjSource = cr.binding.client;
app.adjSourceProcState = clientProcState;
app.adjTarget = s.name;
}
}
if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
app.treatLikeActivity = true;
}
final ActivityRecord a = cr.activity;
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
//當進程adj >0,且activity可見 或者resumed 或 正在暫停,則設置adj = 0
if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
(a.visible || a.state == ActivityState.RESUMED
|| a.state == ActivityState.PAUSING)) {
adj = ProcessList.FOREGROUND_APP_ADJ;
if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
app.cached = false;
app.adjType = "service";
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE;
app.adjSource = a;
app.adjSourceProcState = procState;
app.adjTarget = s.name;
}
}
}
}
}</code></pre>
當adj>0 或 schedGroup為后臺線程組 或procState>2時,雙重循環遍歷:
- 當service已啟動,則procState<=10;
- 當service在30分鐘內活動過,則adj=5,cached=false;
</li>
- 獲取service所綁定的connections
- 當client與當前app同一個進程,則continue;
- 當client進程的ProcState >=cache,則設置為空進程
- 當進程存在顯示的ui,則將當前進程的adj和ProcState值賦予給client進程
- 當不存在顯示的ui,且service上次活動時間距離現在超過30分鐘,則只將當前進程的adj值賦予給client進程
- 當前進程adj > client進程adj的情況
- 當service進程比較重要時,則設置adj >= -11
- 當client進程adj<2,且當前進程adj>2時,則設置adj=2;
- 當client進程adj>1時,則設置adj = clientAdj
- 否則,設置adj <= 1;
- 若client進程不是cache進程,則當前進程也設置為非cache進程
</ul> </li>
- 當綁定的是前臺進程的情況
- 當client進程狀態為前臺時,則設置mayBeTop=true,并設置client進程procState=16
- 當client進程狀態 < 2的前提下:若綁定前臺service,則clientProcState=3;否則clientProcState=6
</ul> </li>
- 當connections并沒有綁定前臺service時,則clientProcState >= 7
- 保證當前進程procState不會必client進程的procState大
</ul> </li>
- 當進程adj >0,且activity可見 或者resumed 或 正在暫停,則設置adj = 0
</ul>
2.4.11 ContentProvider情況
//當adj>0 或 schedGroup為后臺線程組 或procState>2時
for (int provi = app.pubProviders.size()-1;
provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
|| procState > ActivityManager.PROCESS_STATE_TOP);
provi--) {
ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
for (int i = cpr.connections.size()-1;
i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
|| procState > ActivityManager.PROCESS_STATE_TOP);
i--) {
ContentProviderConnection conn = cpr.connections.get(i);
ProcessRecord client = conn.client;
// 當client與當前app同一個進程,則continue;
if (client == app) {
continue;
}
// 計算client進程的adj
int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
int clientProcState = client.curProcState;
//當client進程procState >=14,則設置成procState =16
if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 【】
}
if (adj > clientAdj) {
if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
app.adjType = "cch-ui-provider";
} else {
//沒有ui展示,則保證adj >=0
adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
app.adjType = "provider";
}
app.cached &= client.cached;
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_PROVIDER_IN_USE;
app.adjSource = client;
app.adjSourceProcState = clientProcState;
app.adjTarget = cpr.name;
}
if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
mayBeTop = true;
//當client進程狀態為前臺時,則設置mayBeTop=true,并設置client進程procState=16設置為空進程
clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
} else {
//當client進程狀態 < 2時,則clientProcState=3;
clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
}
}
//procState 比client進程值更大時,則取client端的狀態值。
if (procState > clientProcState) {
procState = clientProcState;
}
if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
}
//當contentprovider存在外部進程依賴(非framework)時
if (cpr.hasExternalProcessHandles()) {
//設置adj =0, procState=6
if (adj > ProcessList.FOREGROUND_APP_ADJ) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.cached = false;
app.adjType = "provider";
app.adjTarget = cpr.name;
}
if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
}
}
}
當adj>0 或 schedGroup為后臺線程組 或procState>2時,雙重循環遍歷:
- 當client與當前app同一個進程,則continue;
- 當client進程procState >=14,則設置成procState =16
- 沒有ui展示,則保證adj >=0
- 當client進程狀態為前臺時,則設置mayBeTop=true,并設置client進程procState=16設置為空進程
- 當client進程狀態 < 2時,則clientProcState=3;
- procState 比client進程值更大時,則取client端的狀態值。
- 當contentprovider存在外部進程依賴(非framework)時,則設置adj =0, procState=6
2.4.12 調整adj
// 當client進程處于top,且procState>2時
if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
switch (procState) {
case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
case ActivityManager.PROCESS_STATE_SERVICE:
//對于procState=6,7,10時,則設置成3
procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
break;
default:
//其他情況,直接設置成2
procState = ActivityManager.PROCESS_STATE_TOP;
break;
}
}
//當procState>= 16時,
if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
if (app.hasClientActivities) {
//當進程存在client activity,則設置procState=15;
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
app.adjType = "cch-client-act";
} else if (app.treatLikeActivity) {
//當進程可以像activity一樣對待時,則設置procState=14;
procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
app.adjType = "cch-as-act";
}
}
//當adj = 5時
if (adj == ProcessList.SERVICE_ADJ) {
if (doingAll) {
//當A類Service個數 > service/3時,則加入到B類Service
app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
mNewNumServiceProcs++;
if (!app.serviceb) {
//當對于低RAM設備,則把該service直接放入B類Service
if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
&& app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
app.serviceHighRam = true;
app.serviceb = true;
} else {
mNewNumAServiceProcs++;
}
} else {
app.serviceHighRam = false;
}
}
//調整adj=8
if (app.serviceb) {
adj = ProcessList.SERVICE_B_ADJ;
}
}
//將計算得到的adj賦給curRawAdj
app.curRawAdj = adj;
//當adj大小上限為maxAdj
if (adj > app.maxAdj) {
adj = app.maxAdj;
if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
}
//對于hasAboveClient=true,則降低該進程adj
app.curAdj = app.modifyRawOomAdj(adj);
app.curSchedGroup = schedGroup;
app.curProcState = procState;
app.foregroundActivities = foregroundActivities;
//返回進程的curRawAdj
return app.curRawAdj; }</code></pre>
2.5 AMS.applyOomAdjLocked
private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
long nowElapsed) {
boolean success = true;
//將curRawAdj賦給setRawAdj
if (app.curRawAdj != app.setRawAdj) {
app.setRawAdj = app.curRawAdj;
}
if (app.curAdj != app.setAdj) {
//將adj值 發送給lmkd守護進程
ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
app.setAdj = app.curAdj;
}
//情況為: waitingToKill
if (app.setSchedGroup != app.curSchedGroup) {
app.setSchedGroup = app.curSchedGroup;
if (app.waitingToKill != null && app.curReceiver == null
&& app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
//殺進程,并設置applyOomAdjLocked過程失敗
app.kill(app.waitingToKill, true);
success = false;
} else {
long oldId = Binder.clearCallingIdentity();
try {
//設置進程組信息
Process.setProcessGroup(app.pid, app.curSchedGroup);
} catch (Exception e) {
} finally {
Binder.restoreCallingIdentity(oldId);
}
//調整進程的swappiness值
Process.setSwappiness(app.pid,
app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
}
}
if (app.repForegroundActivities != app.foregroundActivities) {
app.repForegroundActivities = app.foregroundActivities;
changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
}
if (app.repProcState != app.curProcState) {
app.repProcState = app.curProcState;
changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
if (app.thread != null) {
//設置進程狀態
app.thread.setProcessState(app.repProcState);
}
}
if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
|| ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
app.lastStateTime = now;
//當setProcState = -1或者curProcState與setProcState值不同時,則計算pss下次時間(參數true)
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
mTestPssMode, isSleeping(), now);
} else {
當前時間超過pss下次時間,則請求統計pss,并計算pss下次時間(參數false)
if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
&& now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
mTestPssMode)))) {
requestPssLocked(app, app.setProcState);
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
mTestPssMode, isSleeping(), now);
}
}
if (app.setProcState != app.curProcState) {
boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
if (setImportant && !curImportant) {
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
app.pid, nowElapsed);
}
app.lastCpuTime = app.curCpuTime;
}
maybeUpdateUsageStatsLocked(app, nowElapsed);
app.setProcState = app.curProcState;
if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
app.notCachedSinceIdle = false;
}
if (!doingAll) {
setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
} else {
app.procStateChanged = true;
}
} else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
> USAGE_STATS_INTERACTION_INTERVAL) {
maybeUpdateUsageStatsLocked(app, nowElapsed);
}
if (changes != 0) {
int i = mPendingProcessChanges.size()-1;
ProcessChangeItem item = null;
while (i >= 0) {
item = mPendingProcessChanges.get(i);
if (item.pid == app.pid) {
break;
}
i--;
}
if (i < 0) {
final int NA = mAvailProcessChanges.size();
if (NA > 0) {
item = mAvailProcessChanges.remove(NA-1);
} else {
item = new ProcessChangeItem();
}
item.changes = 0;
item.pid = app.pid;
item.uid = app.info.uid;
if (mPendingProcessChanges.size() == 0) {
mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
}
mPendingProcessChanges.add(item);
}
item.changes |= changes;
item.processState = app.repProcState;
item.foregroundActivities = app.repForegroundActivities;
}
return success;
}</code></pre>
該方法主要功能:
- 把curRawAdj值賦給setRawAdj
- 把adj值 發送給lmkd守護進程
- 當app標記waitingToKill,且沒有廣播接收器運行在該進程,并且調度組為后臺非交互組,則殺掉該進程,設置applyOomAdjLocked過程失敗;
- 設置進程組信息
- 設置進程狀態
- 執行pss統計操作,以及計算下一次pss時間
- 設置進程狀態改變;
三、總結
調整進程的adj的3大護法:
- updateOomAdjLocked :更新adj,當目標進程為空,或者被殺則返回false;否則返回true;
- computeOomAdjLocked :計算adj,返回計算后RawAdj值;
- applyOomAdjLocked :應用adj,當需要殺掉目標進程則返回false;否則返回true。
3.1 updateOomAdjLocked
主要工作:
- 遍歷mLruProcesses進程,更新進程adj,并殺掉滿足以下條件的進程:
- 當curProcState=14或15,且cached進程超過上限(cachedProcessLimit=32)
- 當curProcState=16,且空進程超過上限(TRIM_EMPTY_APPS=8),且空閑時間超過30分鐘
- 當curProcState=16,且空進程超過上限(emptyProcessLimit=16)
</li>
- 根據memFactor來調度執行TrimMemory操作;
</ul>
3.2 computeOomAdjLocked
主要工作:計算進程的adj和procState
- 進程為空的情況
- maxAdj<=0
- 計算各種狀態下(當前顯示activity, 癥結接收的廣播/service等)的adj和procState
- 非前臺activity的情況
- adj > 2的情況
- HeavyWeightProces情況
- HomeProcess情況
- PreviousProcess情況
- 備份進程情況
- Service情況
- ContentProvider情況
- 調整adj
3.3 applyOomAdjLocked
主要工作:
- 把adj值相關信息發送給lmkd守護進程
- 當app標記waitingToKill,且沒有廣播接收器運行在該進程,并且調度組為后臺非交互組,則殺掉該進程;
- 設置進程組信息/進程狀態
- 執行pss統計操作,以及計算下一次pss時間
apply過程中只有當waitingToKill情況下殺掉該進程,則會返回false;否則都是返回true。
來自:http://gityuan.com/2016/08/07/android-adj/