一 进程介绍
安卓基于Linux内核,设备开机后,第一个安卓进程为zygote进程,随后fork system_server(上层),其他上层进程需要通过fork system-server进程来创建。因此进程的创建、调度、销毁是进程篇的核心内容。
- 进程的创建[四大组件通过ams启动进程]
- 进程的调度[前台进程、后台进程、可见/不可见进程、缓存进程]
- 当进程查杀[根据进程当前状态来决定查杀内容]
用户打开app/切换app,都希望能够快速的完成这个操作。应用数据未被加载时,进程不存在,需要冷启动。当启动了大量的进程后,系统内存空间吃紧,那么如何查杀进程又是一个问题。因此在进程启动时需要根据启动意图来更新lru进程的重要性,在查杀时有策略的查杀。
这个进程重要性的更新机制就是OomAdjuster
image.png
二 进程调度介绍
oomadj官方文档
https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/am/OomAdjuster.md
重点总结:
The Android OS runs with limited hardware resources, i.e. CPU/RAM/Power. To strive for the better performance, Oom Ajuster is introduced to tweak the following 3 major factors:
- Process State
- Wildly used by the System Server, i.e., determine if it's foreground or not, change the GC behavior, etc.
- Defined in ActivityManager#PROCESS_STATE_*
- Oom Adj score
- Used by the lmkd to determine which process should be expunged on memory pressure.
- Defined in ProcessList#*_ADJ
- Scheduler Group
- Used to tweak the process group, thread priorities.
- Top process is scheduled to be running on a dedicated big core, while foreground processes take the other big cores; background processes stay with LITTLE cores instead.
翻译一下重点在于三个值的更新
- 更新进程状态.
[computeOomAdjLSP]
state.setCurProcState(procState);
- 更新oom分数.
[computeOomAdjLSP]
state.setCurAdj(adj);
- 更新进程所属的进程组.
switch (curSchedGroup) {
case SCHED_GROUP_BACKGROUND:
processGroup = THREAD_GROUP_BACKGROUND;
break;
case SCHED_GROUP_TOP_APP:
case SCHED_GROUP_TOP_APP_BOUND:
processGroup = THREAD_GROUP_TOP_APP;
break;
case SCHED_GROUP_RESTRICTED:
processGroup = THREAD_GROUP_RESTRICTED;
break;
default:
processGroup = THREAD_GROUP_DEFAULT;
break;
}
4.1 computeOomAdjLSP更新oomadj与procState
// Do final modification to adj. Everything we do between here and applying
// the final setAdj must be done in this function, because we will also use
// it when computing the final cached adj later. Note that we don't need to
// worry about this for max adj above, since max adj will always be used to
// keep it out of the cached vaues.
state.setCurAdj(adj);
state.setCurCapability(capability);
state.setCurrentSchedulingGroup(schedGroup);
state.setCurProcState(procState);
state.setCurRawProcState(procState);
state.updateLastInvisibleTime(hasVisibleActivities);
state.setHasForegroundActivities(foregroundActivities);
state.setCompletedAdjSeq(mAdjSeq);
state.setCurBoundByNonBgRestrictedApp(boundByNonBgRestricted);
// if curAdj or curProcState improved, then this process was promoted
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
|| state.getCurCapability() != prevCapability;
4.2 applyOomAdjLSP设置进程所属状态组
computeOomAdjLSP更新完oomadj与procState后通过applyOomAdjLSP来更新冻结情况与设置进程状态组
/** 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, @OomAdjReason int oomAdjReson) {
// 省略。。
switch (curSchedGroup) {
case SCHED_GROUP_BACKGROUND:
processGroup = THREAD_GROUP_BACKGROUND;
break;
case SCHED_GROUP_TOP_APP:
case SCHED_GROUP_TOP_APP_BOUND:
processGroup = THREAD_GROUP_TOP_APP;
break;
case SCHED_GROUP_RESTRICTED:
processGroup = THREAD_GROUP_RESTRICTED;
break;
default:
processGroup = THREAD_GROUP_DEFAULT;
break;
}
mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
0 /* unused */, app.getPid(), processGroup, app.processName));
---分割线
【OomAdjuster-mProcessGroupHandler】
mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
final int pid = msg.arg1;
final int group = msg.arg2;
if (pid == ActivityManagerService.MY_PID) {
// Skip setting the process group for system_server, keep it as default.
return true;
}
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup "
+ msg.obj + " to " + group);
}
try {
//调用native方法设置进程组
setProcessGroup(pid, group);
} catch (Exception e) {
if (DEBUG_ALL) {
Slog.w(TAG, "Failed setting process group of " + pid + " to " + group, e);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
return true;
});
---分割线
【Process.java】
/**
* Sets the scheduling group for a process and all child threads
* @hide
* @param pid The identifier of the process to change.
* @param group The target group for this process from THREAD_GROUP_*.
*
* @throws IllegalArgumentException Throws IllegalArgumentException if
* <var>tid</var> does not exist.
* @throws SecurityException Throws SecurityException if your process does
* not have permission to modify the given thread, or to use the given
* priority.
*
* group == THREAD_GROUP_DEFAULT means to move all non-background priority
* threads to the foreground scheduling group, but to leave background
* priority threads alone. group == THREAD_GROUP_BACKGROUND moves all
* threads, regardless of priority, to the background scheduling group.
* group == THREAD_GROUP_FOREGROUND is not allowed.
*
* Always sets cpusets.
*/
@UnsupportedAppUsage
public static final native void setProcessGroup(int pid, int group)
throws IllegalArgumentException, SecurityException;
每个进程计算oom时机,计算oom过程,计算oom结果保存,计算结果应用则是几个重点的分析方向。
进程重要性
2.1 Process State
[ActivityManager.java]
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
2.2 OOM_ADJ
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ALLOWLIST;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BACKUP;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BIND_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_COMPONENT_DISABLED;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_EXECUTING_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FINISH_RECEIVER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_GET_PROVIDER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_NONE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_BEGIN;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_PROVIDER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_TASK;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHELL;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_STOP_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SYSTEM_INIT;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UID_IDLE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UI_VISIBILITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UNBIND_SERVICE;
2.3 Scheduler Group
import static android.os.Process.SCHED_OTHER;
import static android.os.Process.THREAD_GROUP_BACKGROUND;
import static android.os.Process.THREAD_GROUP_DEFAULT;
import static android.os.Process.THREAD_GROUP_RESTRICTED;
import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import static android.os.Process.setProcessGroup;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;