一 oomadj機(jī)制引入原因
oomadj機(jī)制是一種內(nèi)存管理機(jī)制许饿,用于處理操作系統(tǒng)中的內(nèi)存不足(Out-Of-Memory)問題。當(dāng)系統(tǒng)的可用內(nèi)存空間不足時(shí)燥筷,操作系統(tǒng)會(huì)使用oomadj機(jī)制來決定哪些進(jìn)程應(yīng)該被終止软瞎,以釋放內(nèi)存闯割。
oomadj機(jī)制引入的原因是為了提高系統(tǒng)的穩(wěn)定性和性能,以及保護(hù)用戶體驗(yàn)省店。oomadj機(jī)制可以根據(jù)進(jìn)程的重要性和內(nèi)存占用情況嚣崭,動(dòng)態(tài)調(diào)整進(jìn)程的優(yōu)先級(jí)笨触,使得系統(tǒng)在內(nèi)存緊張時(shí),優(yōu)先殺死那些不重要或者占用內(nèi)存過多的進(jìn)程雹舀,從而保證那些重要或者用戶可見的進(jìn)程能夠繼續(xù)運(yùn)行芦劣。
oomadj機(jī)制是基于Linux內(nèi)核的oom_score和oom_score_adj機(jī)制的擴(kuò)展,它增加了一些Android特有的因素说榆,例如進(jìn)程的狀態(tài)(前臺(tái)虚吟、后臺(tái)、服務(wù)等)签财、進(jìn)程的類型(系統(tǒng)串慰、應(yīng)用、第三方等)荠卷、進(jìn)程的關(guān)聯(lián)性(是否有其他進(jìn)程依賴它)等模庐,來更精細(xì)地控制進(jìn)程的優(yōu)先級(jí)。
二 oomadj架構(gòu)圖
framework計(jì)算完進(jìn)程oomadj的值以后會(huì)做三件事油宜。
- 將adj同步到lmkd模塊掂碱,當(dāng)psi壓力大時(shí)進(jìn)程查殺
- 通過process.setProcessGroup來調(diào)整進(jìn)程的優(yōu)先級(jí)
- 通過appProfile從libmeminfo獲取lru進(jìn)程的pss值
當(dāng)內(nèi)存不足時(shí),lmkd會(huì)進(jìn)行查殺進(jìn)程慎冤。Oomadj值越大越容易被殺疼燥,相同oomadj優(yōu)先殺pss值大的。
三 oomadj的查詢方法
3.1 查看進(jìn)程的oomadj值
adb shell
cd /proc/pid/
oom_adj oom_score oom_score_adj
cat oom_adj
0 表示前臺(tái)進(jìn)程FOREGROUND_APP_ADJ
oom_adj蚁堤,oom_score和oom_score_adj三者的區(qū)別醉者。oom_adj,oom_score和oom_score_adj都是用來表示進(jìn)程的優(yōu)先級(jí)的指標(biāo)披诗,它們決定了當(dāng)系統(tǒng)內(nèi)存不足時(shí)撬即,哪些進(jìn)程會(huì)被殺死以釋放內(nèi)存12。
oom_adj是一個(gè)舊的打分因子呈队,它的取值范圍是-17到15剥槐,其中-17表示永遠(yuǎn)不會(huì)被殺死,15表示最容易被殺死3?宪摧。oom_adj已經(jīng)在Linux 2.6.36版本中被廢棄粒竖,取而代之的是oom_score_adj12。
oom_score是一個(gè)絕對(duì)值几于,它反映了進(jìn)程的內(nèi)存占用情況蕊苗,越高表示越占用內(nèi)存12。oom_score的取值范圍是0到1000沿彭,其中0表示永遠(yuǎn)不會(huì)被殺死朽砰,1000表示最容易被殺死12。oom_score是由內(nèi)核根據(jù)進(jìn)程的狀態(tài)和oom_score_adj動(dòng)態(tài)計(jì)算的,用戶不能直接修改12锅移。
oom_score_adj是一個(gè)相對(duì)值熔掺,它反映了進(jìn)程的重要性,越低表示越重要12非剃。oom_score_adj的取值范圍是-1000到1000,其中-1000表示永遠(yuǎn)不會(huì)被殺死推沸,1000表示最容易被殺死12备绽。oom_score_adj可以由進(jìn)程自己設(shè)置,或者由系統(tǒng)根據(jù)進(jìn)程的狀態(tài)動(dòng)態(tài)調(diào)整12鬓催。
oom_score和oom_score_adj的關(guān)系是12:
其中肺素,totalvm是進(jìn)程的虛擬內(nèi)存大小,sharedvm是進(jìn)程共享的內(nèi)存大小宇驾。
ProcessStateRecord保存進(jìn)程oomadj
[ProcessStateRecord]
/**
* Current OOM adjustment for this process.
*/
@CompositeRWLock({"mService", "mProcLock"})
private int mCurAdj = ProcessList.INVALID_ADJ;
3.2 查看進(jìn)程pss值
console:/proc/1764 # cat smaps_rollup
0dd6b000-ffff1000 ---p 00000000 00:00 0 [rollup]
Rss: 149452 kB
Pss: 30997 kB
Shared_Clean: 102188 kB
Shared_Dirty: 23284 kB
Private_Clean: 3296 kB
Private_Dirty: 20684 kB
Referenced: 113148 kB
Anonymous: 43700 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 6320 kB
SwapPss: 3771 kB
Locked: 0 kB
從圖中可以看到1764進(jìn)程pss占用300997Kb倍靡。
3.3 查看進(jìn)程是否被凍結(jié)
console:/dev/freezer/frozen # cat cgroup.procs
1764
2013
2149
2595
2714
2936
3122
3529
上面的進(jìn)程就是已經(jīng)被凍結(jié)的進(jìn)程號(hào)。
U有改變课舍。路徑不對(duì)了塌西。
四 framewok中用于輔助oomadj機(jī)制表示進(jìn)程狀態(tài)的類
4.1 ProcessList
// OOM adjustments for processes in various states:
// Uninitialized value for any major or minor adj fields
public static final int INVALID_ADJ = -10000;
// Adjustment used in certain places where we don't know it yet.
// (Generally this is something that is going to be cached, but we
// don't know the exact value in the cached range to assign yet.)
public static final int UNKNOWN_ADJ = 1001;
// This is a process only hosting activities that are not visible,
// so it can be killed without any disruption.
public static final int CACHED_APP_MAX_ADJ = 999;
public static final int CACHED_APP_MIN_ADJ = 900;
// This is the oom_adj level that we allow to die first. This cannot be equal to
// CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
// CACHED_APP_MAX_ADJ.
public static final int CACHED_APP_LMK_FIRST_ADJ = 950;
// Number of levels we have available for different service connection group importance
// levels.
static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
// The B list of SERVICE_ADJ -- these are the old and decrepit
// services that aren't as shiny and interesting as the ones in the A list.
public static final int SERVICE_B_ADJ = 800;
// This is the process of the previous application that the user was in.
// This process is kept above other things, because it is very common to
// switch back to the previous app. This is important both for recent
// task switch (toggling between the two top recent apps) as well as normal
// UI flow such as clicking on a URI in the e-mail app to view in the browser,
// and then pressing back to return to e-mail.
public static final int PREVIOUS_APP_ADJ = 700;
// This is a process holding the home application -- we want to try
// avoiding killing it, even if it would normally be in the background,
// because the user interacts with it so much.
public static final int HOME_APP_ADJ = 600;
// This is a process holding an application service -- killing it will not
// have much of an impact as far as the user is concerned.
public static final int SERVICE_ADJ = 500;
// This is a process with a heavy-weight application. It is in the
// background, but we want to try to avoid killing it. Value set in
// system/rootdir/init.rc on startup.
public static final int HEAVY_WEIGHT_APP_ADJ = 400;
// This is a process currently hosting a backup operation. Killing it
// is not entirely fatal but is generally a bad idea.
public static final int BACKUP_APP_ADJ = 300;
// This is a process bound by the system (or other app) that's more important than services but
// not so perceptible that it affects the user immediately if killed.
public static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
// This is a process hosting services that are not perceptible to the user but the
// client (system) binding to it requested to treat it as if it is perceptible and avoid killing
// it if possible.
public static final int PERCEPTIBLE_MEDIUM_APP_ADJ = 225;
// This is a process only hosting components that are perceptible to the
// user, and we really want to avoid killing them, but they are not
// immediately visible. An example is background music playback.
public static final int PERCEPTIBLE_APP_ADJ = 200;
// This is a process only hosting activities that are visible to the
// user, so we'd prefer they don't disappear.
public static final int VISIBLE_APP_ADJ = 100;
static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
// This is a process that was recently TOP and moved to FGS. Continue to treat it almost
// like a foreground app for a while.
// @see TOP_TO_FGS_GRACE_PERIOD
public static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
// This is the process running the current foreground app. We'd really
// rather not kill it!
public static final int FOREGROUND_APP_ADJ = 0;
// This is a process that the system or a persistent process has bound to,
// and indicated it is important.
public static final int PERSISTENT_SERVICE_ADJ = -700;
// This is a system persistent process, such as telephony. Definitely
// don't want to kill it, but doing so is not completely fatal.
public static final int PERSISTENT_PROC_ADJ = -800;
// The system process runs at the default adjustment.
public static final int SYSTEM_ADJ = -900;
// Special code for native processes that are not being managed by the system (so
// don't have an oom adj assigned by the system).
public static final int NATIVE_ADJ = -1000;
4.2 ProcessStateEnum.aidl
/**
* Defines the PROCESS_STATE_* values used by ActivityManager.
* These values are shared by Java and native side.
* {@hide}
*/
@Backing(type="int")
enum ProcessStateEnum {
/** @hide Not a real process state. */
UNKNOWN = -1,
/** @hide Process is a persistent system process. */
PERSISTENT = 0,
/** @hide Process is a persistent system process and is doing UI. */
PERSISTENT_UI = 1,
/** @hide Process is hosting the current top activities. Note that this covers
* all activities that are visible to the user. */
TOP = 2,
/** @hide Process is bound to a TOP app. */
BOUND_TOP = 3,
/** @hide Process is hosting a foreground service. */
FOREGROUND_SERVICE = 4,
/** @hide Process is hosting a foreground service due to a system binding. */
BOUND_FOREGROUND_SERVICE = 5,
/** @hide Process is important to the user, and something they are aware of. */
IMPORTANT_FOREGROUND = 6,
/** @hide Process is important to the user, but not something they are aware of. */
IMPORTANT_BACKGROUND = 7,
/** @hide Process is in the background transient so we will try to keep running. */
TRANSIENT_BACKGROUND = 8,
/** @hide Process is in the background running a backup/restore operation. */
BACKUP = 9,
/** @hide Process is in the background running a service. Unlike oom_adj, this level
* is used for both the normal running in background state and the executing
* operations state. */
SERVICE = 10,
/** @hide Process is in the background running a receiver. Note that from the
* perspective of oom_adj, receivers run at a higher foreground level, but for our
* prioritization here that is not necessary and putting them below services means
* many fewer changes in some process states as they receive broadcasts. */
RECEIVER = 11,
/** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
TOP_SLEEPING = 12,
/** @hide Process is in the background, but it can't restore its state so we want
* to try to avoid killing it. */
HEAVY_WEIGHT = 13,
/** @hide Process is in the background but hosts the home activity. */
HOME = 14,
/** @hide Process is in the background but hosts the last shown activity. */
LAST_ACTIVITY = 15,
/** @hide Process is being cached for later use and contains activities. */
CACHED_ACTIVITY = 16,
/** @hide Process is being cached for later use and is a client of another cached
* process that contains activities. */
CACHED_ACTIVITY_CLIENT = 17,
/** @hide Process is being cached for later use and has an activity that corresponds
* to an existing recent task. */
CACHED_RECENT = 18,
/** @hide Process is being cached for later use and is empty. */
CACHED_EMPTY = 19,
/** @hide Process does not exist. */
NONEXISTENT = 20,
}
此aild為系統(tǒng)側(cè)定義,app開發(fā)者需要使用ActivityManager來定義筝尾。
4.2.1 ActivityManager.java
/** @hide Process is hosting a foreground service due to a system binding. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE =
ProcessStateEnum.BOUND_FOREGROUND_SERVICE;
---分割線
/** @hide */
public static String procStateToString(int procState) {
final String procStateStr;
switch (procState) {
case ActivityManager.PROCESS_STATE_PERSISTENT:
procStateStr = "PER ";
break;
case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
procStateStr = "PERU";
break;
case ActivityManager.PROCESS_STATE_TOP:
procStateStr = "TOP ";
break;
case ActivityManager.PROCESS_STATE_BOUND_TOP:
procStateStr = "BTOP";
break;
case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
procStateStr = "FGS ";
break;
case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
procStateStr = "BFGS";
break;
case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
procStateStr = "IMPF";
break;
case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
procStateStr = "IMPB";
break;
case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
procStateStr = "TRNB";
break;
case ActivityManager.PROCESS_STATE_BACKUP:
procStateStr = "BKUP";
break;
case ActivityManager.PROCESS_STATE_SERVICE:
procStateStr = "SVC ";
break;
case ActivityManager.PROCESS_STATE_RECEIVER:
procStateStr = "RCVR";
break;
case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
procStateStr = "TPSL";
break;
case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
procStateStr = "HVY ";
break;
case ActivityManager.PROCESS_STATE_HOME:
procStateStr = "HOME";
break;
case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
procStateStr = "LAST";
break;
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
procStateStr = "CAC ";
break;
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
procStateStr = "CACC";
break;
case ActivityManager.PROCESS_STATE_CACHED_RECENT:
procStateStr = "CRE ";
break;
case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
procStateStr = "CEM ";
break;
case ActivityManager.PROCESS_STATE_NONEXISTENT:
procStateStr = "NONE";
break;
default:
procStateStr = "??";
break;
}
return procStateStr;
}
4.2 和4.2.1 oomadj和procState的區(qū)別和聯(lián)系
系統(tǒng)側(cè)用ProcessStateRecord.mAdjType來保存進(jìn)程狀態(tài)類型捡需。
進(jìn)程查殺主要依據(jù)還是oomadj的值,但是進(jìn)程當(dāng)前的狀態(tài)沒法從oomadj的值上直觀體現(xiàn)筹淫,所有引入了進(jìn)程狀態(tài)和adjType站辉,進(jìn)程狀態(tài)procState和進(jìn)程adjType永遠(yuǎn)保持一致。
4.3 Process.java
THREAD_GROUP_* 用于為pid設(shè)置group-> setProcessGroup
// Keep in sync with SP_* constants of enum type SchedPolicy
// declared in system/core/include/cutils/sched_policy.h,
// except THREAD_GROUP_DEFAULT does not correspond to any SP_* value.
/**
* Default thread group -
* has meaning with setProcessGroup() only, cannot be used with setThreadGroup().
* When used with setProcessGroup(), the group of each thread in the process
* is conditionally changed based on that thread's current priority, as follows:
* threads with priority numerically less than THREAD_PRIORITY_BACKGROUND
* are moved to foreground thread group. All other threads are left unchanged.
* @hide
*/
public static final int THREAD_GROUP_DEFAULT = -1;
/**
* Background thread group - All threads in
* this group are scheduled with a reduced share of the CPU.
* Value is same as constant SP_BACKGROUND of enum SchedPolicy.
* @hide
*/
public static final int THREAD_GROUP_BACKGROUND = 0;
/**
* Foreground thread group - All threads in
* this group are scheduled with a normal share of the CPU.
* Value is same as constant SP_FOREGROUND of enum SchedPolicy.
* Not used at this level.
* @hide
**/
private static final int THREAD_GROUP_FOREGROUND = 1;
/**
* System thread group.
* @hide
**/
public static final int THREAD_GROUP_SYSTEM = 2;
/**
* Application audio thread group.
* @hide
**/
public static final int THREAD_GROUP_AUDIO_APP = 3;
/**
* System audio thread group.
* @hide
**/
public static final int THREAD_GROUP_AUDIO_SYS = 4;
/**
* Thread group for top foreground app.
* @hide
**/
public static final int THREAD_GROUP_TOP_APP = 5;
/**
* Thread group for RT app.
* @hide
**/
public static final int THREAD_GROUP_RT_APP = 6;
/**
* Thread group for bound foreground services that should
* have additional CPU restrictions during screen off
* @hide
**/
public static final int THREAD_GROUP_RESTRICTED = 7;
4.4 觸發(fā)oomadj的原因
@IntDef(prefix = {"OOM_ADJ_REASON_"}, value = {
OOM_ADJ_REASON_NONE,
OOM_ADJ_REASON_ACTIVITY,
OOM_ADJ_REASON_FINISH_RECEIVER,
OOM_ADJ_REASON_START_RECEIVER,
OOM_ADJ_REASON_BIND_SERVICE,
OOM_ADJ_REASON_UNBIND_SERVICE,
OOM_ADJ_REASON_START_SERVICE,
OOM_ADJ_REASON_GET_PROVIDER,
OOM_ADJ_REASON_REMOVE_PROVIDER,
OOM_ADJ_REASON_UI_VISIBILITY,
OOM_ADJ_REASON_ALLOWLIST,
OOM_ADJ_REASON_PROCESS_BEGIN,
OOM_ADJ_REASON_PROCESS_END,
OOM_ADJ_REASON_SHORT_FGS_TIMEOUT,
OOM_ADJ_REASON_SYSTEM_INIT,
OOM_ADJ_REASON_BACKUP,
OOM_ADJ_REASON_SHELL,
OOM_ADJ_REASON_REMOVE_TASK,
OOM_ADJ_REASON_UID_IDLE,
OOM_ADJ_REASON_STOP_SERVICE,
OOM_ADJ_REASON_EXECUTING_SERVICE,
OOM_ADJ_REASON_RESTRICTION_CHANGE,
OOM_ADJ_REASON_COMPONENT_DISABLED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface OomAdjReason {}
5 oomadj源碼流程解析
@GuardedBy({"mService", "mProcLock"})
private boolean updateOomAdjLSP(ProcessRecord app, String oomAdjReason) {
if (app == null || !mConstants.OOMADJ_UPDATE_QUICK) {
updateOomAdjLSP(oomAdjReason);
return true;
}
// 1. 判斷oomadj是否正在進(jìn)行
if (checkAndEnqueueOomAdjTargetLocked(app)) {
// Simply return true as there is an oomAdjUpdate ongoing
return true;
}
try {
//2. 設(shè)置oomadj正在進(jìn)行中
mOomAdjUpdateOngoing = true;
//3. 執(zhí)行oomadj計(jì)算
return performUpdateOomAdjLSP(app, oomAdjReason);
} finally {
// Kick off the handling of any pending targets enqueued during the above update
mOomAdjUpdateOngoing = false;
updateOomAdjPendingTargetsLocked(oomAdjReason);
}
}
5.1 checkAndEnqueueOomAdjTargetLocked
/**
* Check if there is an ongoing oomAdjUpdate, enqueue the given process record
* to {@link #mPendingProcessSet} if there is one.
*
* @param app The target app to get an oomAdjUpdate, or a full oomAdjUpdate if it's null.
* @return {@code true} if there is an ongoing oomAdjUpdate.
*/
@GuardedBy("mService")
private boolean checkAndEnqueueOomAdjTargetLocked(@Nullable ProcessRecord app) {
if (!mOomAdjUpdateOngoing) {
return false;
}
if (app != null) {
mPendingProcessSet.add(app);
} else {
mPendingFullOomAdjUpdate = true;
}
return true;
}
5.2 performUpdateOomAdjLSP
private boolean performUpdateOomAdjLSP(ProcessRecord app, String oomAdjReason) {
// 1.獲取頂層app的processRecord
final ProcessRecord topApp = mService.getTopApp();
// 2. trace記錄损姜,并記錄本次開始時(shí)間
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReason);
mService.mOomAdjProfiler.oomAdjStarted();
//3. 更新當(dāng)前進(jìn)程的oomadj值
boolean success = performUpdateOomAdjLSP(app, cachedAdj, topApp,
SystemClock.uptimeMillis());
//4. 找到可達(dá)進(jìn)程
// Next to find out all its reachable processes
ArrayList<ProcessRecord> processes = mTmpProcessList;
boolean containsCycle = collectReachableProcessesLocked(mPendingProcessSet,
processes, uids);
int size = processes.size();
if (size > 0) {
mAdjSeq--;
// 5. 更新可達(dá)進(jìn)程的oomadj饰剥,什么叫可達(dá)進(jìn)程: pending中的進(jìn)程、bindservice摧阅、contentprovider的進(jìn)程
// eg1.: final ProcessServiceRecord psr = pr.mServices;
// eg2.: final ProcessProviderRecord ppr = pr.mProviders;
// 計(jì)算可達(dá)進(jìn)程的oomadj
// Update these reachable processes
updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false);
mTmpProcessList.clear();
// 6 結(jié)束計(jì)時(shí)汰蓉,函數(shù)返回
mService.mOomAdjProfiler.oomAdjEnded();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return true;
5.3 performUpdateOomAdjLSP
private boolean performUpdateOomAdjLSP(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, long now) {
// 獲取當(dāng)前進(jìn)程的UidRecord
UidRecord uidRec = app.getUidRecord();
if (uidRec != null) {
if (DEBUG_UID_OBSERVERS) {
Slog.i(TAG_UID_OBSERVERS, "Starting update of " + uidRec);
}
//2. 將Uid中狀態(tài)恢復(fù)默認(rèn),mForegroundServices=false逸尖,procstate = PROCESS_STATE_CACHED_EMPTY
uidRec.reset();
}
//3.
computeOomAdjLSP(app, cachedAdj, topApp, false, now, false, true);
//4
return applyOomAdjLSP(app, false, now, SystemClock.elapsedRealtime());
5.3.1 computeOomAdjLSP
@GuardedBy({"mService", "mProcLock"})
private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
boolean computeClients) {
//1. 保存當(dāng)前狀態(tài)
int prevAppAdj = state.getCurAdj();
int prevProcState = state.getCurProcState();
int prevCapability = state.getCurCapability();
final ProcessServiceRecord psr = app.mServices;
// 2. 如果當(dāng)前進(jìn)程是大于前臺(tái)進(jìn)程古沥,例如系統(tǒng)進(jìn)程則無需計(jì)算。
if (state.getMaxAdj() <= ProcessList.FOREGROUND_APP_ADJ) {
// 3. 如果當(dāng)前app是ams保存的topapp則直接賦值即可娇跟。
if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
// The last app on the list is the foreground app.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
state.setAdjType("top-activity");
foregroundActivities = true;
hasVisibleActivities = true;
procState = PROCESS_STATE_CUR_TOP;
state.bumpAllowStartFgsState(PROCESS_STATE_TOP);
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
}
//4. 如果正在執(zhí)行動(dòng)畫岩齿、或者測(cè)試中,則賦值高優(yōu)先級(jí)
} else if (state.isRunningRemoteAnimation()) {
adj = ProcessList.VISIBLE_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
state.setAdjType("running-remote-anim");
procState = PROCESS_STATE_CUR_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
}
} else if (app.getActiveInstrumentation() != null) {
// Don't want to kill running instrumentation.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
state.setAdjType("instrumentation");
procState = PROCESS_STATE_FOREGROUND_SERVICE;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
}
//5. 如果正在接收廣播則賦值接廣播狀態(tài)
} else if (state.getCachedIsReceivingBroadcast(mTmpBroadcastQueue)) {
// An app that is currently receiving a broadcast also
// counts as being in the foreground for OOM killer purposes.
// It's placed in a sched group based on the nature of the
// broadcast as reflected by which queue it's active in.
// 5.1 正在接收廣播狀態(tài)的進(jìn)程被認(rèn)為是前臺(tái)進(jìn)程苞俘。
adj = ProcessList.FOREGROUND_APP_ADJ;
//5.2 狀態(tài)設(shè)置為廣播
state.setAdjType("broadcast");
procState = ActivityManager.PROCESS_STATE_RECEIVER;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
}
// 6. 如果正在執(zhí)行service盹沈,也設(shè)置為前臺(tái),設(shè)置類型為"exec-service"
} else if (psr.numberOfExecutingServices() > 0) {
// An app that is currently executing a service callback also
// counts as being in the foreground.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = psr.shouldExecServicesFg()
? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
state.setAdjType("exec-service");
procState = PROCESS_STATE_SERVICE;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
}
} else if (app == topApp) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
state.setAdjType("top-sleeping");
foregroundActivities = true;
procState = PROCESS_STATE_CUR_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
}
// 7. 進(jìn)程不為以上類型,認(rèn)為是后臺(tái)進(jìn)程乞封。
} else {
// As far as we know the process is empty. We may change our mind later.
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
// At this point we don't actually know the adjustment. Use the cached adj
// value that the caller wants us to.
adj = cachedAdj;
procState = PROCESS_STATE_CACHED_EMPTY;
if (!state.containsCycle()) {
state.setCached(true);
state.setEmpty(true);
state.setAdjType("cch-empty");
}
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
}
}
// 還有其他provider做裙、uioverlay等判斷,不再一一列舉肃晚,總之根據(jù)狀態(tài)設(shè)置1.schedGroup 2.adj 3.procState 4.setAdjType
// 8. 如果計(jì)算后的oomadj狀態(tài)比之前提升了锚贱,那么需要對(duì)進(jìn)程進(jìn)行提權(quán)處理。
// if curAdj or curProcState improved, then this process was promoted
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
|| state.getCurCapability() != prevCapability;
6 applyOomAdjLSP 處理oomadj的計(jì)算結(jié)果
/** Applies the computed oomadj, procstate and sched group values and freezes them in set* */
@GuardedBy({"mService", "mProcLock"})
private boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now,
long nowElapsed) {
boolean success = true;
// 1. 當(dāng)前的adj和上次統(tǒng)計(jì)的adj不一樣关串。
if (state.getCurAdj() != state.getSetAdj()) {
// 1.1 更新processList中進(jìn)程的oomadj拧廊,里面會(huì)調(diào)用writeLmkd(buf, null);將pid的adj寫入lmkd模塊。
ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj());
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
String msg = "Set " + app.getPid() + " " + app.processName + " adj "
+ state.getCurAdj() + ": " + state.getAdjType();
reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
}
state.setSetAdj(state.getCurAdj());
state.setVerifiedAdj(ProcessList.INVALID_ADJ);
}
// 2. 更新進(jìn)程組信息晋修。
final int curSchedGroup = state.getCurrentSchedulingGroup();
switch (curSchedGroup) {
case ProcessList.SCHED_GROUP_BACKGROUND:
processGroup = THREAD_GROUP_BACKGROUND;
break;
case ProcessList.SCHED_GROUP_TOP_APP:
case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
processGroup = THREAD_GROUP_TOP_APP;
break;
case ProcessList.SCHED_GROUP_RESTRICTED:
processGroup = THREAD_GROUP_RESTRICTED;
break;
default:
processGroup = THREAD_GROUP_DEFAULT;
break;
}
// 2.1 調(diào)用Process的native方法setProcessGroup設(shè)置進(jìn)程組
setProcessGroup(pid, group);
// 2.2 根據(jù)進(jìn)程組的情況設(shè)置線程優(yōu)先級(jí)狀態(tài)吧碾,具體有哪些值可Process.THREAD_PRIORITY_***
setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
setThreadPriority(app.getPid(), 0);
setThreadPriority(app.getPid(), 0);
setThreadPriority(renderThreadTid, THREAD_PRIORITY_DISPLAY);
// 3. 省略部分信息。
return success;