1、AMS中的進程管理
final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
在AMS的內部屬性中使用mLruProcesses集合保存所有的進程信息,AMS將所有進程按照優先級從低到高的順序保存着對應的ProcessRecord信息,即排在前面的進程優先級越低,當系統內存不足時優先被Killer殺死;
在AMS的工作過程中,會不斷調用updateLruProcessLocked()方法進行進程排序,在mLruProcesses()中保存按照以下規則保存數據
在AMS中越重要的進程會放在mLruProcesses集合的最後面,正在使用交互的進程會保存在最後,然後按照其他進程、Service進程、Activity進程的順序重要行逐步增加,Activity進程的重要性最高,爲了區分各個進程的位置,AMS中引入mLruProcessServiceStart和mLruProcessActivityStart變量保存二者的起始位置,在添加時當進程中包含活動則添加到mLruProcessActivityStart之後,如果不包含活動但包含Service服務,則添加到mLruProcessServiceStart之後;
- updateLruProcessLocked源碼
final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
ProcessRecord client) {
final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
|| app.treatLikeActivity || app.recentTasks.size() > 0;//1、
final boolean hasService = false;
if (!activityChange && hasActivity) { // 如果activityChange爲false則無需改變位置
return;
}
mLruSeq++; // 更新編號
final long now = SystemClock.uptimeMillis();
app.lastActivityTime = now; // 保存更新的時間
if (hasActivity) { // 如果包含Activity,
final int N = mLruProcesses.size();
if (N > 0 && mLruProcesses.get(N-1) == app) {
return;
}
} else {
if (mLruProcessServiceStart > 0 // 不包含Activit但已經存在其他段的最末尾,也無需更新
&& mLruProcesses.get(mLruProcessServiceStart-1) == app) {
return;
}
}
int lrui = mLruProcesses.lastIndexOf(app); // 獲取目前位置的index
if (app.persistent && lrui >= 0) {
return;
}
if (lrui >= 0) {
if (lrui < mLruProcessActivityStart) { // 如果index小於mLruProcessActivityStart,則Activity段前移一位
mLruProcessActivityStart--;
}
if (lrui < mLruProcessServiceStart) {//如果index小於mLruProcessServiceStart,則Activity段前移一位
mLruProcessServiceStart--;
}
mLruProcesses.remove(lrui); //移除原來的app信息
}
int nextIndex; //
if (hasActivity) {
final int N = mLruProcesses.size();
if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
&& mLruProcessActivityStart < (N - 1)) {
mLruProcesses.add(N - 1, app); // 如果進程不存在活動,但recentTasks存在任務則添加到最後位置
final int uid = app.info.uid;
for (int i = N - 2; i > mLruProcessActivityStart; i--) {
ProcessRecord subProc = mLruProcesses.get(i);
if (subProc.info.uid == uid) { // 遍歷集合中進程,匹配uid相等的進程
if (mLruProcesses.get(i - 1).info.uid != uid) {//處理其他進程,將該用戶進程前移,其他進程後移
ProcessRecord tmp = mLruProcesses.get(i);
mLruProcesses.set(i, mLruProcesses.get(i - 1));
mLruProcesses.set(i - 1, tmp);
i--;
}
} else {
break;
}
}
} else {
mLruProcesses.add(app); // 直接添加進程信息
}
nextIndex = mLruProcessServiceStart;
} else if (hasService) { 存在Service服務
mLruProcesses.add(mLruProcessActivityStart, app); // 保存在Service服務的開始位置
nextIndex = mLruProcessServiceStart;
mLruProcessActivityStart++; // mLruProcessActivityStart後移
} else {
int index = mLruProcessServiceStart;
if (client != null) {
int clientIndex = mLruProcesses.lastIndexOf(client);//獲取當前客戶端最高級的位置
if (clientIndex <= lrui) {
clientIndex = lrui; // 如果最高級小則賦值最高級爲lrui
}
if (clientIndex >= 0 && index > clientIndex) {
index = clientIndex;
}
}
mLruProcesses.add(index, app); // 保存在頭部位置
nextIndex = index-1;
mLruProcessActivityStart++;
mLruProcessServiceStart++;
}
for (int j=app.connections.size()-1; j>=0; j--) {
ConnectionRecord cr = app.connections.valueAt(j);
if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
&& cr.binding.service.app != null
&& cr.binding.service.app.lruSeq != mLruSeq
&& !cr.binding.service.app.persistent) {
nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
"service connection", cr, app);
}
}
for (int j=app.conProviders.size()-1; j>=0; j--) {
ContentProviderRecord cpr = app.conProviders.get(j).provider;
if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
"provider reference", cpr, app);
}
}
}
在updateLruProcessLocked()中主要執行流程:
- 判斷進程中是否包含活動,如果activityChange爲false則無需改變位置
- 如果當前進程存在活動信息,則判斷當前進程是不是在集合的最後一位,如果是則無需變換位置
- 從集合中取出進程本身的位置index,判斷mLruProcessActivityStart和mLruProcessServiceStart在移除進程後是否需要前移,並從集合中移除進程對象
- 如果進程中包含Activity,則直接添加進程到集合最後,但如果不包含活動只是recentTasks存在執行的任務則替換爲集合的最後一個,然後遍歷集合,這裏遍歷的目的是爲了集合進程的公平性,在一個用戶的進程被插在最後時,該用戶的其他進程需要前移,其他用戶的進程需要後移;
- 對於Service服務則直接保存在服務段的首位,然後後移mLruProcessActivityStart位置
- 對於其他進程則保存在頭部位置,但保存的原則就是不能超過其客戶端爲優先級
- 最後調用updateLruProcessInternalLocked()更新綁定服務進程和包含ContentProvider的進程信息
關於AMS中進程的管理就分析結束了,簡單來說就是AMS會自動更新集合中進程 的位置,從而區分進程的區域和優先級部分,下面一起看下Android 中的進程管理機制;
2、Android與Linux協作內存管理
Android的內存管理實際是通過與Linux協作完成的,Linux通過OOM KIller機制通知Android端執行內存釋放操作,關於OOM機制主要包含以下特點:
- 在Android中運行一個叫OOM進程,該進程啓動後首先會向Linux內核中註冊成爲OOM Killer
- 當內核內存管理模塊檢測到內存低時會通知OOM進程,然後OOM Killer執行內存釋放
- Android在啓動一個新的進程時,AMS會把該進程的oom_adj值告訴 OOM Killer,oom_adj值表示進程的優先級(Android中 0 ~ 15)值越低則越重要,所謂的前臺進程、後臺進程、空進程最後都會反應在oom_adj值上;
- OOM Killer收到內存釋放的消息後,按照預先設置的優先級開始強制退出低優先級的進程
2.1、AMS進程的優先級(在OOM 中設置 oom_adj的值)
在AMS執行過程中會不斷的更新進程的優先級,主要體現是根據進程條件設置進程中對應的adj信息,然後將賦值的adj更新到OOM機制中改變進程的等級信息,Android中區分進程的原則
- 前臺進程 :ForeGround進程表示當前用戶正在交互的進程,需要滿足以下條件
- 具備正在可交互的前臺Activity
- 包含和前臺交互Activity綁定的Service服務
- 含有一個正在運行的前臺服務,即Service中調用了startForGround()
- Service正在執行系列的生命週期(onxxx())方法
- Receiver執行onReceive()
- 可視進程:Visiable進程表示當前對用戶可見的進程,滿足以下條件
- 具備可視的Activit,這裏的可視指的是調用了onPause()之後處於可見但不交互的狀態
- 具備服務於可視Activity的Service服務
- 服務進程
- 具備正常調用startService()啓動運行的Service服務,但不具備上面兩個條件,沒有和前臺或可視的Activity交互,只是服務自己在執行數據處理
- 後臺進程
- 不滿足上面的三個進程條件,但具備與用戶不可見的Activity,即執行過onStop()之後的活動界面
- 後臺空進程:沒有任何運行組件的進程
2.2、updateOomAdjLocked()
在前面的ActivityManagerService的內存管理分析知道,程序在activityIdleInternalLocked()的最後調用了trimApplications()執行進程的管理
final void trimApplicationsLocked() {
for (i=mRemovedProcesses.size()-1; i>=0; i--) { // 1、刪除mRemoveProcess進程中的數據
12210 final ProcessRecord app = mRemovedProcesses.get(i); // 獲取進程app
12211 if (app.activities.size() == 0&& app.curReceiver == null && app.services.size() == 0) {//確定進程爲空
12218 if (app.pid > 0 && app.pid != MY_PID) {
12219 app.kill("empty", false); // 直接殺死進程
12220 } else {
12222 app.thread.scheduleExit(); // 執行進程退出
12226 }
12227 cleanUpApplicationRecordLocked(app, false, -1);
12228 mRemovedProcesses.remove(i); // 移除進程信息
12235 }
12236 }
updateOomAdjLocked() //2、爲所有的進程更新 oom adj 的值
}
trimApplications()中直接調用 trimApplicationsLocked()方法,執行刪除mRemovedProcesses集合中保存的進程,mRemovedProcesses主要保存即將被清除的進程,一般mRemoveProcess集合中數據來源:
- 當進程被crash後會將該進程添加到集合中;
- 當程序出現ANR時且用戶點擊關閉程序時,將進程添加到集合中;
- 程序調用AMS.killBackgroundProcess()時,系統並不會直接殺死進程而是會將進程先添加到集合中;
程序遍歷mRemovedProcesses集合中的進程信息,然後判斷當前進程是否爲空進程,然後分別執行進程殺死和進程退出操作,最後從集合中清除進程信息,在清除mRemovedProcesses中進程後,調用updateOomAdjLocked()判斷系統是否支持OOM Killer,並更新所有進程的優先級和管理進程,在查看源碼之前先介紹下ProcessRecord類
- ProcessRecord內部屬性與OOM相關的變量
curAdj:進程當前的adj值,反應了進程的優先級
setAdj:上一個設置的adj的值
curRawAdj:第一次對app評級後計算的adj的值,
setRawAdj:刪一個curRawAdj設置的值
maxAdj:OOM的最大調整值
2.3、優先級計算和進程管理
updateOomAdjLocked()第二部分,主要計算每個進程的優先級,即oom_adj的值,如果底層Linux包含OOM Killer返回true,否則返回false;
final void updateOomAdjLocked() {
final ActivityRecord TOP_ACT = resumedAppLocked(); // 1、獲取最頂部的resume的ActivityRecord對象
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;// 2、獲取頂部活動所在的進程
final int N = mLruProcesses.size();
for (int i=mActiveUids.size()-1; i>=0; i--) {
final UidRecord uidRec = mActiveUids.valueAt(i);
uidRec.reset(); // 復位所有的UidRecord對象,UidRecord主要保存每個用戶的最高優先級進程
}
final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; //獲取允許空進程的數量,此處返回16
final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit; //獲取允許的後臺進程數16
//爲後臺進程、空進程開闢位置,此處計算結果爲(906-900+1)/2 = 3
int numSlots = (ProcessList.CACHED_APP_MAX_ADJ //
- ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; // 計算當前系統中空進程的數量
int emptyFactor = numEmptyProcs/numSlots;// 計算每個slot中保存的進程數量
int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; // 後臺進程的adj= 900
int nextCachedAdj = curCachedAdj+1; // 下一個位置+1
int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; // 空進程adj=900
int nextEmptyAdj = curEmptyAdj+2; // 下一個位置+2
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i); // 遍歷所有的進程ProcessRecord ,計算oom_adj的值
if (!app.killedByAm && app.thread != null) {
computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
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:
app.curRawAdj = curCachedAdj; //賦值後臺進程
app.curAdj = app.modifyRawOomAdj(curCachedAdj);
if (curCachedAdj != nextCachedAdj) {
stepCached++; // 累計當前adj值中保存的進程數
if (stepCached >= cachedFactor) { // 超過每個slot數量後使用下一個next slot位置
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);
break;
}
}
}
}
}
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (!app.killedByAm && app.thread != null) {
applyOomAdjLocked(app, true, now, nowElapsed); // 更新進程的adj值
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) {//並且當前進程空閒時間超過設置要求的時間30min
app.kill("empty for "
+ ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
/ 1000) + "s", true);
} else {
numEmpty++;
if (numEmpty > emptyProcessLimit) {// 空進程超過限制殺掉進程,此處設置爲16
app.kill("empty #" + numEmpty, true);
}
}
break;
default:
mNumNonCachedProcs++;
break;
}
//對於單獨進程的空進程,直接殺死進程
if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
app.kill("isolated not needed", true);
} else {
final UidRecord uidRec = app.uidRecord;
if (uidRec != null) {
uidRec.ephemeral = app.info.isInstantApp();
if (uidRec.curProcState > app.curProcState) { // 更新用戶的最高優先級
uidRec.curProcState = app.curProcState;
}
}
}
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
&& !app.killedByAm) {
numTrimming++; // 統計優先級低於Home進程的,表明此更加進程不重要
}
}
}
在updateOomAdjLocked()中主要是計算進程的優先級,同時決定進程的生死,主要任務如下:
- 根據系統設置的常量計算系統允許的空進程、後臺進程的數量,設置空進程、後臺進程的adj值
- 遍歷所有的後臺進程,調用computeOomAdjLocked()計算進程值;
- 對於不能計算的則直接判斷是後臺進程還是空進程
- 調用applyOomAdjLocked()將進程的等級更新到OOM中
- 倒敘遍歷所有進程信息統計後臺進程數量,如果超過限定值則直接殺死進程,此處也顯示了集合中靠前的進程容易被殺死
- 對於空進程如果超過系統允許存在的數量,且空閒時間超過設置的30min,或總數超過設置的上限將殺死進程
- 對於單獨進程的空進程,直接殺死進程
- 統計優先級低於Home進程的數量,保存在numTrimming中
2.4、通知進程釋放內存
final int numCachedAndEmpty = numCached + numEmpty; // 計算後臺進程和空進程數量之和,確定內存等級
int memFactor;
//如果後臺進程小於5,空進程小於8
if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
&& numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {//總計小於等於 3
memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; // 設置爲CRITICAL級別
} else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { //總計不超過5
memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; // 設置爲Low級別
} else {
memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; // 設置爲MODERATE級別
}
} else {
memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; // 設置爲normal級別
}
mLastMemoryLevel = memFactor; // 保存最新等級
if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { //當內存不爲normal時,需要執行內存回收
if (mLowRamStartTime == 0) {
mLowRamStartTime = now; // 保存低內存時間
}
}
switch (memFactor) { //根據內存狀況,設置fgTrimLevel等級
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;
}
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
&& !app.killedByAm) { // 處理優先級低於Home進程的,調用scheduleTrimMemory()方法執行內存回收
app.thread.scheduleTrimMemory(curLevel);
}else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
&& !app.killedByAm) { // 處理優先級爲HEAVY_WEIGHT
if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
&& app.thread != null) {
app.thread.scheduleTrimMemory(
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) {
try {
app.thread.scheduleTrimMemory(level);
} catch (RemoteException e) {
}
}
app.pendingUiClean = false;
}
if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
try {
app.thread.scheduleTrimMemory(fgTrimLevel);
} catch (RemoteException e) {
}
}
app.trimMemoryLevel = fgTrimLevel;
}
}
本部分主要是處理系統內存緊張時,通知運行的進程回收內存的機制:
- 首先計算系統中後臺進程和空進程的總數,並根據進程總數、空進程數、後臺進程數設置系統內存等級,空進程數、後臺進程數越少表示系統內存越緊張;
- 當內存等級不爲normal時,則表明系統內存緊張需要回收內存,此時需要通知進程釋放內存
- 針對不同進程調用app.thread.scheduleTrimMemory()方法執行內存回收,在scheduleTrimMemory()中最終回調到Activity的o nTrimMemory()方法
到此Android系統中對進程的管理就分析結束了,簡單的說就是會不斷計算和更新進程的優先級,然後根據設置的上限條件決定殺死哪些進程保留哪些進程,對於存活的進程Amdroid中也會進行進一步操作,就是通知進程的內存回收,程序根據系統中進程的存活量確定當前內存等級,然後根據進程優先級調用系統的內存回收方法,處理上面的整個流程外,還有一個方法沒有分析就是computeOomAdjLocked(),下面看看它是如何計算進程優先級的;
2.5、computeOomAdjLocked
11517 if (app == TOP_APP) {//1、 判斷當前進程是否爲TOP_APP,TOP_APP保存當前正在運行的ProcessRecord對象
11519 adj = FOREGROUND_APP_ADJ; // 設置爲FOREGROUND_APP_ADJ,優先級最高爲0
11520 schedGroup = Process.THREAD_GROUP_DEFAULT;
11521 app.adjType = "top-activity";
11522 } else if (app.instrumentationClass != null) { // 2、是否有自定義的instrumentationClass
11524 adj = FOREGROUND_APP_ADJ; // 設置爲優先級最高0
11525 schedGroup = Process.THREAD_GROUP_DEFAULT;
11526 app.adjType = "instrumentation";
11527 } else if (app.curReceiver != null || // 3、判斷有持久的Activity、Service、Receiver設置爲優先級最高 0
11528 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
11531 adj = FOREGROUND_APP_ADJ;
11532 schedGroup = Process.THREAD_GROUP_DEFAULT;
11533 app.adjType = "broadcast";
11534 } else if (app.executingServices.size() > 0) {
11537 adj = FOREGROUND_APP_ADJ;
11538 schedGroup = Process.THREAD_GROUP_DEFAULT;
11539 app.adjType = "exec-service";
11540 } else if (app.foregroundServices) { // 4、判斷當前是否爲前臺服務,設置優先級爲 1
11542 adj = PERCEPTIBLE_APP_ADJ;
11543 schedGroup = Process.THREAD_GROUP_DEFAULT;
11544 app.adjType = "foreground-service";
11545 } else if (app.forcingToForeground != null) { //5、判斷用戶是否強制調到前臺,設置優先級1
11547 adj = PERCEPTIBLE_APP_ADJ;
11548 schedGroup = Process.THREAD_GROUP_DEFAULT;
11549 app.adjType = "force-foreground";
11550 app.adjSource = app.forcingToForeground;
11551 } else if (app == mHomeProcess) { //6、判斷是否爲Home進程,設置優先級 4
11559 adj = HOME_APP_ADJ;
11560 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11561 app.adjType = "home";
}else if ((N=app.activities.size()) != 0) {
11568 N = app.activities.size();
11569 for (int j=0; j<N; j++) {
11570 if (app.activities.get(j).visible) {
11572 app.hidden = false;
11573 adj = VISIBLE_APP_ADJ;
11574 schedGroup = Process.THREAD_GROUP_DEFAULT; //7、包含Activity數目大於0,且包含可見的Activity存在,設置1
11575 app.adjType = "visible";
11576 break;
11577 }
11578 }
11579 }else {
11582 app.hidden = true;
11583 app.empty = true;
11584 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11585 adj = hiddenAdj; // 8、其他進程設置爲hiddenAdj
11586 app.adjType = "bg-empty";
11587 }
app.adjSeq = mAdjSeq;
app.curRawAdj = adj; // 賦值第一次估算的adj
if (mBackupTarget != null && app == mBackupTarget.app) {//9、判斷是否爲mBackuptarget進程,設置優先級 2
11600 if (adj > BACKUP_APP_ADJ) {
11602 adj = BACKUP_APP_ADJ;
11603 app.adjType = "backup";
11604 app.hidden = false;
11605 }
11606 }
// 10、判斷app中服務進程(進程中運行Service但不屬於前臺服務)
11608 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
11609 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Iterator<ServiceRecord> jt = app.services.iterator();
11614 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11615 ServiceRecord s = jt.next(); //遍歷所有的Service
11616 if (s.startRequested) { // 根據startRequested判斷Service是否啓動,如果啓動過超過待機時間,設置優先級 2
adj = SECONDARY_SERVER_ADJ;
}
}
if (cr.binding.client == app) { // 如果Service有綁定的app,則保護app的優先級即可
11649 continue; }
int clientAdj = computeOomAdjLocked(client, myHiddenAdj, TOP_APP, true); // 遞歸調用第二次估算,以優先級高爲準
ActivityRecord a = cr.activity; // 判斷是否進程是否包含resume或pause的Activity,設置爲優先級 0
11688 if (a != null && adj > FOREGROUND_APP_ADJ && (a.state == ActivityState.RESUMED
11690 || a.state == ActivityState.PAUSING)) {
11691 adj = FOREGROUND_APP_ADJ;
11692 schedGroup = Process.THREAD_GROUP_DEFAULT;
}
app.curAdj = adj; // 最終的adj
app.curSchedGroup = schedGroup;
關於應用進程優先級的更新細節見代碼註釋,源碼部分很多請讀者自行查看,主要就是根據前臺進程、前臺服務、後臺進程等設置對應的adj的值,在計算完adj之後每個進程都有了各自的優先級順序,將最終計算的結果保存在app.curAdj中,那此時就代表當前進程的優先級了;
本文從源碼的角度分析了AMS是如何管理內存的,主要分析了AMS如何管理應用程序進程管理、OOM Killer機制如何設備中的進程管理,通過對整個內存管理的學習,對系統程序之間的協調運作有了更好的認知,那關於AMS的部分就到此結束了。