一 oomadj机制引入原因
oomadj机制是一种内存管理机制,用于处理操作系统中的内存不足(Out-Of-Memory)问题。当系统的可用内存空间不足时,操作系统会使用oomadj机制来决定哪些进程应该被终止,以释放内存。
oomadj机制引入的原因是为了提高系统的稳定性和性能,以及保护用户体验。oomadj机制可以根据进程的重要性和内存占用情况,动态调整进程的优先级,使得系统在内存紧张时,优先杀死那些不重要或者占用内存过多的进程,从而保证那些重要或者用户可见的进程能够继续运行。
oomadj机制是基于Linux内核的oom_score和oom_score_adj机制的扩展,它增加了一些Android特有的因素,例如进程的状态(前台、后台、服务等)、进程的类型(系统、应用、第三方等)、进程的关联性(是否有其他进程依赖它)等,来更精细地控制进程的优先级。
二 oomadj架构图
framework计算完进程oomadj的值以后会做三件事。
- 将adj同步到lmkd模块,当psi压力大时进程查杀
- 通过process.setProcessGroup来调整进程的优先级
- 通过appProfile从libmeminfo获取lru进程的pss值
当内存不足时,lmkd会进行查杀进程。Oomadj值越大越容易被杀,相同oomadj优先杀pss值大的。
三 oomadj的查询方法
3.1 查看进程的oomadj值
adb shell
cd /proc/pid/
oom_adj oom_score oom_score_adj
cat oom_adj
0 表示前台进程FOREGROUND_APP_ADJ
oom_adj,oom_score和oom_score_adj三者的区别。oom_adj,oom_score和oom_score_adj都是用来表示进程的优先级的指标,它们决定了当系统内存不足时,哪些进程会被杀死以释放内存¹²。
oom_adj是一个旧的打分因子,它的取值范围是-17到15,其中-17表示永远不会被杀死,15表示最容易被杀死³⁴。oom_adj已经在Linux 2.6.36版本中被废弃,取而代之的是oom_score_adj¹²。
oom_score是一个绝对值,它反映了进程的内存占用情况,越高表示越占用内存¹²。oom_score的取值范围是0到1000,其中0表示永远不会被杀死,1000表示最容易被杀死¹²。oom_score是由内核根据进程的状态和oom_score_adj动态计算的,用户不能直接修改¹²。
oom_score_adj是一个相对值,它反映了进程的重要性,越低表示越重要¹²。oom_score_adj的取值范围是-1000到1000,其中-1000表示永远不会被杀死,1000表示最容易被杀死¹²。oom_score_adj可以由进程自己设置,或者由系统根据进程的状态动态调整¹²。
oom_score和oom_score_adj的关系是¹²:
其中,totalvm是进程的虚拟内存大小,sharedvm是进程共享的内存大小。
ProcessStateRecord保存进程oomadj
[ProcessStateRecord]
/**
* Current OOM adjustment for this process.
*/
@CompositeRWLock({"mService", "mProcLock"})
private int mCurAdj = ProcessList.INVALID_ADJ;
3.2 查看进程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进程pss占用300997Kb。
3.3 查看进程是否被冻结
console:/dev/freezer/frozen # cat cgroup.procs
1764
2013
2149
2595
2714
2936
3122
3529
上面的进程就是已经被冻结的进程号。
U有改变。路径不对了。
四 framewok中用于辅助oomadj机制表示进程状态的类
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为系统侧定义,app开发者需要使用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的区别和联系
系统侧用ProcessStateRecord.mAdjType来保存进程状态类型。
进程查杀主要依据还是oomadj的值,但是进程当前的状态没法从oomadj的值上直观体现,所有引入了进程状态和adjType,进程状态procState和进程adjType永远保持一致。
4.3 Process.java
THREAD_GROUP_* 用于为pid设置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 触发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是否正在进行
if (checkAndEnqueueOomAdjTargetLocked(app)) {
// Simply return true as there is an oomAdjUpdate ongoing
return true;
}
try {
//2. 设置oomadj正在进行中
mOomAdjUpdateOngoing = true;
//3. 执行oomadj计算
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记录,并记录本次开始时间
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReason);
mService.mOomAdjProfiler.oomAdjStarted();
//3. 更新当前进程的oomadj值
boolean success = performUpdateOomAdjLSP(app, cachedAdj, topApp,
SystemClock.uptimeMillis());
//4. 找到可达进程
// 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. 更新可达进程的oomadj,什么叫可达进程: pending中的进程、bindservice、contentprovider的进程
// eg1.: final ProcessServiceRecord psr = pr.mServices;
// eg2.: final ProcessProviderRecord ppr = pr.mProviders;
// 计算可达进程的oomadj
// Update these reachable processes
updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false);
mTmpProcessList.clear();
// 6 结束计时,函数返回
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) {
// 获取当前进程的UidRecord
UidRecord uidRec = app.getUidRecord();
if (uidRec != null) {
if (DEBUG_UID_OBSERVERS) {
Slog.i(TAG_UID_OBSERVERS, "Starting update of " + uidRec);
}
//2. 将Uid中状态恢复默认,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. 保存当前状态
int prevAppAdj = state.getCurAdj();
int prevProcState = state.getCurProcState();
int prevCapability = state.getCurCapability();
final ProcessServiceRecord psr = app.mServices;
// 2. 如果当前进程是大于前台进程,例如系统进程则无需计算。
if (state.getMaxAdj() <= ProcessList.FOREGROUND_APP_ADJ) {
// 3. 如果当前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. 如果正在执行动画、或者测试中,则赋值高优先级
} 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. 如果正在接收广播则赋值接广播状态
} 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 正在接收广播状态的进程被认为是前台进程。
adj = ProcessList.FOREGROUND_APP_ADJ;
//5.2 状态设置为广播
state.setAdjType("broadcast");
procState = ActivityManager.PROCESS_STATE_RECEIVER;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
}
// 6. 如果正在执行service,也设置为前台,设置类型为"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. 进程不为以上类型,认为是后台进程。
} 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等判断,不再一一列举,总之根据状态设置1.schedGroup 2.adj 3.procState 4.setAdjType
// 8. 如果计算后的oomadj状态比之前提升了,那么需要对进程进行提权处理。
// if curAdj or curProcState improved, then this process was promoted
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
|| state.getCurCapability() != prevCapability;
6 applyOomAdjLSP 处理oomadj的计算结果
/** 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. 当前的adj和上次统计的adj不一样。
if (state.getCurAdj() != state.getSetAdj()) {
// 1.1 更新processList中进程的oomadj,里面会调用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. 更新进程组信息。
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 调用Process的native方法setProcessGroup设置进程组
setProcessGroup(pid, group);
// 2.2 根据进程组的情况设置线程优先级状态,具体有哪些值可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;