### AMS调度策略深度源码解析
一、AMS调度核心数据结构与初始化
1.关键类定义(源码路径:frameworks/base/services/core/java/com/android/server/am/)
ProcessRecord:封装进程信息(UID、PID、组件列表等)
````
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
int _uid, String _sdkSandboxClientAppPackage, int _definingUid,
String _definingProcessName) {
mService = _service;
mProcLock = _service.mProcLock;
info = _info;
ProcessInfo procInfo = null;
if (_service.mPackageManagerInt != null) {
if (_definingUid > 0) {
ArrayMap<String, ProcessInfo> processes =
_service.mPackageManagerInt.getProcessesForUid(_definingUid);
if (processes != null) procInfo = processes.get(_definingProcessName);
} else {
ArrayMap<String, ProcessInfo> processes =
_service.mPackageManagerInt.getProcessesForUid(_uid);
if (processes != null) procInfo = processes.get(_processName);
}
if (procInfo != null && procInfo.deniedPermissions == null
&& procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
&& procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
&& procInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_DEFAULT) {
// If this process hasn't asked for permissions to be denied, or for a
// non-default GwpAsan mode, or any other non-default setting, then we don't
// care about it.
procInfo = null;
}
}
processInfo = procInfo;
isolated = Process.isIsolated(_uid);
isSdkSandbox = Process.isSdkSandboxUid(_uid);
appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID
&& UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID);
uid = _uid;
userId = UserHandle.getUserId(_uid);
processName = _processName;
sdkSandboxClientAppPackage = _sdkSandboxClientAppPackage;
if (isSdkSandbox) {
final ApplicationInfo clientInfo = getClientInfoForSdkSandbox();
sdkSandboxClientAppVolumeUuid = clientInfo != null
? clientInfo.volumeUuid : null;
} else {
sdkSandboxClientAppVolumeUuid = null;
}
mPersistent = false;
mRemoved = false;
mProfile = new ProcessProfileRecord(this);
mServices = new ProcessServiceRecord(this);
mProviders = new ProcessProviderRecord(this);
mReceivers = new ProcessReceiverRecord(this);
mErrorState = new ProcessErrorStateRecord(this);
mState = new ProcessStateRecord(this);
mOptRecord = new ProcessCachedOptimizerRecord(this);
final long now = SystemClock.uptimeMillis();
mProfile.init(now);
mOptRecord.init(now);
mState.init(now);
mWindowProcessController = new WindowProcessController(
mService.mActivityTaskManager, info, processName, uid, userId, this, this);
mPkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
}
````
ActivityRecord:描述Activity状态(所属Task、生命周期状态)
`
class ActivityRecord {
TaskRecord task; // 所属任务栈
int state; // 生命周期状态(如RESUMED、PAUSED)
ProcessRecord app; // 宿主进程
}
`
TaskRecord:管理Activity任务栈(基于LIFO原则)
`
class TaskRecord {
ArrayList<ActivityRecord> mActivities; // 栈内Activity列表
int mTaskId; // 任务栈唯一标识
}`
2.调度策略初始化(源码路径:SystemServer.java)
AMS在SystemServer启动阶段初始化调度策略:
` // SystemServer.startBootstrapServices()
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemProcess(); // 注册系统进程
mActivityManagerService.systemReady(); // 启动调度策略 `
二、进程优先级调度机制(ADJ算法)
ADJ计算入口(源码路径:ActivityManagerService.java)
// frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
void updateOomAdjLocked(ProcessRecord app) {
int adj = computeOomAdjLocked(app); // 核心计算逻辑
app.setAdj = adj;
applyOomAdjLocked(app); // 将adj值写入内核
}
ADJ分级规则(源码路径:ProcessList.java)
ADJ写入内核(源码路径:ProcessList.java)
AMS通过setOomAdj()将adj值写入/proc/<pid>/oom_score_adj:
ProcessList.setOomAdj(app.pid, app.uid, adj);
三、LRU进程管理机制
LRU列表更新(源码路径:ActivityStackSupervisor.java)
AMS通过updateLruProcessLocked()维护进程LRU列表:
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void updateLruProcessLocked(ProcessRecord app) {
if (app.activities.size() > 0) {
mLruProcesses.remove(app); // 移除旧位置
mLruProcesses.add(app); // 添加至列表尾部
}
}
LRU触发场景
Activity切换:当用户切换到新Activity时,宿主进程被移至LRU尾部
Service绑定:服务进程在绑定后提升LRU优先级
内存回收策略
AMS在内存不足时遍历LRU列表,按以下顺序终止进程:
Cached进程 → Service进程 → 后台进程
四、Activity调度与超时机制
Activity启动流程(源码路径:ActivityStarter.java)
AMS处理startActivity()请求的核心逻辑:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
mSupervisor.resumeFocusedStackTopActivityLocked(); // 恢复栈顶Activity
mTargetStack.startActivityLocked(...); // 启动新Activity
}
超时处理(源码路径:ActivityStack.java)
AMS通过schedulePauseTimeout()检测Activity暂停超时:
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
void schedulePauseTimeout(ActivityRecord r) {
mHandler.postDelayed(() -> {
if (r.state != PAUSED) {
destroyActivityLocked(r); // 强制销毁未及时暂停的Activity
}
}, PAUSE_TIMEOUT); // 默认500ms[1,6](@ref)
}
总结:
调试命令:
adb shell dumpsys activity processes # 查看当前进程ADJ与LRU列表 adb shell cat /proc//oom_score_adj # 查看进程实际ADJ值