AMS调度策略

162 阅读2分钟

### 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)​

image.png

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)
}

总结:

image.png

​调试命令​​:

adb shell dumpsys activity processes # 查看当前进程ADJ与LRU列表 adb shell cat /proc//oom_score_adj # 查看进程实际ADJ值