深入AMS源码(四)——ActivityManagerService的进程管理

本文详细分析了Android ActivityManagerService (AMS) 中的进程管理,包括AMS如何根据优先级保存进程信息、Android与Linux协作的内存管理机制、OOM Killer的工作原理以及AMS如何设置和更新进程的oom_adj值。通过理解这些机制,可以更好地了解Android系统如何决定进程的生死和内存回收策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、AMS中的进程管理

final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 

在AMS的内部属性中使用mLruProcesses集合保存所有的进程信息,AMS将所有进程按照优先级从低到高的顺序保存着对应的ProcessRecord信息,即排在前面的进程优先级越低,当系统内存不足时优先被Killer杀死;

在AMS的工作过程中,会不断调用updateLruProcessLocked()方法进行进程排序,在mLruProcesses()中保存按照以下规则保存数据
在这里插入图片描述
在AMS中越重要的进程会放在mLruProcesses集合的最后面,正在使用交互的进程会保存在最后,然后按照其他进程、Service进程、Activity进程的顺序重要行逐步增加,Activity进程的重要性最高,为了区分各个进程的位置,AMS中引入mLruProcessServiceStart和mLruProcessActivityStart变量保存二者的起始位置,在添加时当进程中包含活动则添加到mLruProcessActivityStart之后,如果不包含活动但包含Service服务,则添加到mLruProcessServiceStart之后;

  • updateLruProcessLocked源码
final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
            ProcessRecord client) {
   
        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
                || app.treatLikeActivity || app.recentTasks.size() > 0;//1、
        final boolean hasService = false; 
        if (!activityChange && hasActivity) {
    // 如果activityChange为false则无需改变位置
            return;
        }

        mLruSeq++; // 更新编号
        final long now = SystemClock.uptimeMillis();
        app.lastActivityTime = now; // 保存更新的时间

        if (hasActivity) {
    // 如果包含Activity,
            final int N = mLruProcesses.size();
            if (N > 0 && mLruProcesses.get(N-1) == app) {
    
                return;
            }
        } else {
   
            if (mLruProcessServiceStart > 0 // 不包含Activit但已经存在其他段的最末尾,也无需更新
                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   
                return;
            }
        }

        int lrui = mLruProcesses.lastIndexOf(app); // 获取目前位置的index
        if (app.persistent && lrui >= 0) {
   
            return;
        }
        if (lrui >= 0) {
    
            if (lrui < mLruProcessActivityStart) {
    // 如果index小于mLruProcessActivityStart,则Activity段前移一位
                mLruProcessActivityStart--;
            }
            if (lrui < mLruProcessServiceStart) {
   //如果index小于mLruProcessServiceStart,则Activity段前移一位
                mLruProcessServiceStart--;
            }
            mLruProcesses.remove(lrui); //移除原来的app信息
        }

        int nextIndex; // 
        if (hasActivity) {
   
            final int N = mLruProcesses.size();
            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
                    && mLruProcessActivityStart < (N - 1)) {
   
                mLruProcesses.add(N - 1, app); // 如果进程不存在活动,但recentTasks存在任务则添加到最后位置
                final int uid = app.info.uid;
                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
   
                    ProcessRecord subProc = mLruProcesses.get(i);
                    if (subProc.info.uid == uid) {
    // 遍历集合中进程,匹配uid相等的进程
                        if (mLruProcesses.get(i - 1).info.uid != uid) {
   //处理其他进程,将该用户进程前移,其他进程后移
                            ProcessRecord tmp = mLruProcesses.get(i);
                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
                            mLruProcesses.set(i - 1, tmp);
                            i--;
                        }
                    } else {
   
                        break;
                    }
                }
            } else {
   
                mLruProcesses.add(app); // 直接添加进程信息
            }
            nextIndex = mLruProcessServiceStart;
        } else if (hasService) {
    存在Service服务
            mLruProcesses.add(mLruProcessActivityStart, app); // 保存在Service服务的开始位置
            nextIndex = mLruProcessServiceStart;
            mLruProcessActivityStart++; // mLruProcessActivityStart后移
        } else  {
   
            int index = mLruProcessServiceStart;
            if (client != null) {
   
                int clientIndex = mLruProcesses.lastIndexOf(client);//获取当前客户端最高级的位置
                if (clientIndex <= lrui) {
   
                    clientIndex = lrui; // 如果最高级小则赋值最高级为lrui
                }
                if (clientIndex >= 0 && index > clientIndex) {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值