
AndroID应用程序主要以activity/service/contentprovIDer/broadcastrecevIEr四大组件组成,ActivityManagerService根据四大组件的生命周期函数,以及进程的创建,死亡等来动态调节进程自身的状态,影响进程的cpu占用时间,内存IO等资源分配。进程有两个比较重要的状态值,即adj(定义在ProcessList.java)和procState(定义在ActivityManager.java),控制缓存进程和空进程个数上限依赖于procState,控制APP执行handleLowMemory()的触发时机等。
adj值如下:
static final int INVALID_ADJ = -10000;static final int UNKNowN_ADJ = 1001;static final int CACHED_APP_MAX_ADJ = 999;static final int CACHED_APP_MIN_ADJ = 900;static final int CACHED_APP_LMK_FirsT_ADJ = 950;static final int CACHED_APP_importANCE_LEVELS = 5;static final int SERVICE_B_ADJ = 800;static final int PREVIoUS_APP_ADJ = 700;static final int HOME_APP_ADJ = 600;static final int SERVICE_ADJ = 500;static final int HEAVY_WEIGHT_APP_ADJ = 400;static final int BACKUP_APP_ADJ = 300;static final int PERCEPTIBLE_LOW_APP_ADJ = 250;static final int PERCEPTIBLE_APP_ADJ = 200;static final int VISIBLE_APP_ADJ = 100;static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;static final int FOREGROUND_APP_ADJ = 0;static final int PERSISTENT_SERVICE_ADJ = -700;static final int PERSISTENT_PROC_ADJ = -800;static final int SYstem_ADJ = -900;static final int NATIVE_ADJ = -1000;// 定义在ActivityManager.java里的procState值public static final int PROCESS_STATE_UNKNowN = -1;public static final int PROCESS_STATE_PERSISTENT = 0;public static final int PROCESS_STATE_PERSISTENT_UI = 1;public static final int PROCESS_STATE_top = 2;public static final int PROCESS_STATE_FOREGROUND_SERVICE_LOCATION = 3;public static final int PROCESS_STATE_BOUND_top = 4;public static final int PROCESS_STATE_FOREGROUND_SERVICE = 5;public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 6;public static final int PROCESS_STATE_important_FOREGROUND = 7;public static final int PROCESS_STATE_important_BACKGROUND = 8;public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 9;public static final int PROCESS_STATE_BACKUP = 10;public static final int PROCESS_STATE_SERVICE = 11;public static final int PROCESS_STATE_RECEIVER = 12;public static final int PROCESS_STATE_top_SLEEPing = 13;public static final int PROCESS_STATE_HEAVY_WEIGHT = 14;public static final int PROCESS_STATE_HOME = 15;public static final int PROCESS_STATE_LAST_ACTIVITY = 16;public static final int PROCESS_STATE_CACHED_ACTIVITY = 17;public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 18;public static final int PROCESS_STATE_CACHED_RECENT = 19;public static final int PROCESS_STATE_CACHED_EMPTY = 20;public static final int PROCESS_STATE_NONEXISTENT = 21;OomAdjusterAndroid10.0以后将adj相关的处理移到OomAdjuster中,adj的值越大,则进程越容易被杀
updateOomAdjLocked:更新运行中的进程的adj值computeOomAdjLocked:计算adj值applyOomAdjLocked:应用adj值,通过调整oom_score_adj来影响进程寿命(Lowmemorykiller杀进程策略);ProcessRecord涉及到adj成员变量// 当前进程最大的adj值int maxAdj;// 当前进程的原始adj值int curRawAdj;// 当前进程上一次的adj值int setRawAdj;// 当前进程的adj值int curAdj;// 当前进程上一次的adj值int setAdj;// 当前进程调度组int mCurSchedGroup;// 当前进程上一次调度组int setSchedGroup;// adj的类型,便于分辨场景String adjType;更新adj值的常见场景:
static final String OOM_ADJ_REASON_METHOD = "updateOomAdj";static final String OOM_ADJ_REASON_NONE = OOM_ADJ_REASON_METHOD + "_meh";// activity相关static final String OOM_ADJ_REASON_ACTIVITY = OOM_ADJ_REASON_METHOD + "_activityChange";// 广播相关static final String OOM_ADJ_REASON_FINISH_RECEIVER = OOM_ADJ_REASON_METHOD + "_finishReceiver";static final String OOM_ADJ_REASON_START_RECEIVER = OOM_ADJ_REASON_METHOD + "_startReceiver";// 服务相关static final String OOM_ADJ_REASON_BIND_SERVICE = OOM_ADJ_REASON_METHOD + "_bindService";static final String OOM_ADJ_REASON_UNBIND_SERVICE = OOM_ADJ_REASON_METHOD + "_unbindService";static final String OOM_ADJ_REASON_START_SERVICE = OOM_ADJ_REASON_METHOD + "_startService";// ProvIDer相关static final String OOM_ADJ_REASON_GET_PROVIDER = OOM_ADJ_REASON_METHOD + "_getProvIDer";static final String OOM_ADJ_REASON_REMOVE_PROVIDER = OOM_ADJ_REASON_METHOD + "_removeProvIDer";static final String OOM_ADJ_REASON_UI_VISIBIliTY = OOM_ADJ_REASON_METHOD + "_uiVisibility";static final String OOM_ADJ_REASON_WHITEList = OOM_ADJ_REASON_METHOD + "_whiteListChange";// 进程相关static final String OOM_ADJ_REASON_PROCESS_BEGIN = OOM_ADJ_REASON_METHOD + "_processBegin";static final String OOM_ADJ_REASON_PROCESS_END = OOM_ADJ_REASON_METHOD + "_processEnd";进程组在AndroID中,Process.setProcessGroup(int pID, int group)用来设置进程的调度组。调度组会影响进程的cpu占用时间,内存IO等资源分配
// ProcessList.java后台进程组static final int SCHED_GROUP_BACKGROUND = 0;受限制的组static final int SCHED_GROUP_RESTRICTED = 1;默认进程组static final int SCHED_GROUP_DEFAulT = 2;top进程组public static final int SCHED_GROUP_top_APP = 3;static final int SCHED_GROUP_top_APP_BOUND = 4;updateOomAdjLocked函数分析1 获取前台进程2 获取缓存进程的数量3 一些CachedAdj相关变量的初始化, 系统常量获取4 重置mProcessList列表进程中的adj值,以及进程状态// 获取前台进程final ProcessRecord top_APP = mService.gettopAppLocked();// 缓存进程的数量final int N = mProcessList.getLruSizeLocked();// 避免重复计算设计, 在computeOomAdjLocked中有用到来作为判断依据mAdJseq++;// 最大空进程数量限制final int emptyProcesslimit = mConstants.CUR_MAX_EMPTY_PROCESSES;// 最大缓存进程数量限制final int cachedProcesslimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcesslimit;// 进程卡槽数量,Android10.0为10final int numSlots = (ProcessList.CACHED_APP_MAX_ADJ - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2 / ProcessList.CACHED_APP_importANCE_LEVELS;int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHIDdenProcs;if (numEmptyProcs > cachedProcesslimit) { numEmptyProcs = cachedProcesslimit;}// cache adj的最小值为ProcessList.CACHED_APP_MIN_ADJint curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;int nextCachedAdj = curCachedAdj + (ProcessList.CACHED_APP_importANCE_LEVELS * 2);int curCachedImpAdj = 0;int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_importANCE_LEVELS;int nextEmptyAdj = curEmptyAdj + (ProcessList.CACHED_APP_importANCE_LEVELS * 2);boolean retryCycles = false;// 重置进程状态for (int i = N - 1; i >= 0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); app.containsCycle = false; app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY); app.setCurRawAdj(ProcessList.UNKNowN_ADJ);}- 5 遍历mLruProcesses列表,计算每个进程的adj值 - 6 如果getCurProcState状态为cache相关,则当前进程的adj值在当前的基础上加1或者加ProcessList.CACHED_APP_importANCE_LEVELS * 2中的一个 - 7 设置进程的原始adj值,以及adj值 ```java // 更新mLruProcesses缓存进程的adj值 for (int i = N - 1; i >= 0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null) { app.procStateChanged = false; // 计算adj值 computeOomAdjLocked(app, ProcessList.UNKNowN_ADJ, top_APP, true, Now, false);
// 稍后需要重新计算adj值 retryCycles |= app.containsCycle; if (app.curAdj >= ProcessList.UNKNowN_ADJ) { // cache adj 的范围在(CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ)之间 switch (app.getCurProcState()) { case PROCESS_STATE_CACHED_ACTIVITY: case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: case ActivityManager.PROCESS_STATE_CACHED_RECENT: boolean inGroup = false; if (app.connectionGroup != 0) { if (lastCachedGroupUID == app.uID && lastCachedGroup == app.connectionGroup) { if (app.connectionimportance > lastCachedGroupimportance) { lastCachedGroupimportance = app.connectionimportance; // curCachedAdj的值小于nextCachedAdj,并且小于CACHED_APP_MAX_ADJ // adj的值将要在现在的基础上增大 if (curCachedAdj < nextCachedAdj && curCachedAdj < ProcessList.CACHED_APP_MAX_ADJ) { curCachedImpAdj++; } } inGroup = true; } else { lastCachedGroupUID = app.uID; lastCachedGroup = app.connectionGroup; lastCachedGroupimportance = app.connectionimportance; } } if (!inGroup && curCachedAdj != nextCachedAdj) { stepCached++; curCachedImpAdj = 0; if (stepCached >= cachedFactor) { stepCached = 0; curCachedAdj = nextCachedAdj; // 将nextCachedAdj加2个CACHED_APP_importANCE_LEVELS,移动到下一个等级的值 nextCachedAdj += ProcessList.CACHED_APP_importANCE_LEVELS * 2; // cache adj的值最大为ProcessList.CACHED_APP_MAX_ADJ if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; } } } // 设置app进程的原始adj值 app.setCurRawAdj(curCachedAdj + curCachedImpAdj); // 调整adj值 app.curAdj = app.modifyRawOomAdj(curCachedAdj + curCachedImpAdj); break; default: if (curEmptyAdj != nextEmptyAdj) { stepEmpty++; if (stepEmpty >= emptyFactor) { stepEmpty = 0; curEmptyAdj = nextEmptyAdj; nextEmptyAdj += ProcessList.CACHED_APP_importANCE_LEVELS * 2; if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; } } } // 设置app进程的原始adj值 app.setCurRawAdj(curEmptyAdj); // 调整adj值 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); break; } }}}
<br>- 8 是否需要重新计算某些进程的adj值```javaint cycleCount = 0;// retryCycles为true, 某些进程需要重新计算adj值while (retryCycles && cycleCount < 10) { cycleCount++; retryCycles = false; // 重新计算adj值 for (int i = 0; i < N; i++) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null && app.containsCycle == true) { if (computeOomAdjLocked(app, app.getCurRawAdj(), top_APP, true, Now, true)) { retryCycles = true; } } }}-9 收尾工作,再次遍历mProcessList列表,cache进程超过限定kill掉,空进程超过系统限定kill掉
for (int i = N - 1; i >= 0; i--) { ProcessRecord app = mProcessList.mLruProcesses.get(i); if (!app.killedByAm && app.thread != null) { switch (app.getCurProcState()) { case PROCESS_STATE_CACHED_ACTIVITY: case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: mNumCachedHIDdenProcs++; numCached++; if (app.connectionGroup != 0) { if (lastCachedGroupUID == app.info.uID && lastCachedGroup == app.connectionGroup) { numCachedExtraGroup++; } else { lastCachedGroupUID = app.info.uID; lastCachedGroup = app.connectionGroup; } } else { lastCachedGroupUID = lastCachedGroup = 0; } // cache进程超过cachedProcesslimit限定, kill掉 if ((numCached - numCachedExtraGroup) > cachedProcesslimit) { app.kill("cached #" + numCached, true); } break; case PROCESS_STATE_CACHED_EMPTY: // 超过指定空进程数,kill掉 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES && (app.lastActivityTime < oldTime) ) { app.kill("empty for " + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) / 1000) + "s", true); } else { numEmpty++; if ((numEmpty > emptyProcesslimit)) { app.kill("empty #" + numEmpty, true); } } break; default: mNumNonCachedProcs++; break; } // app.isolated为true,也没有service运行, kill掉 if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) { app.kill("isolated not needed", true); } if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME && !app.killedByAm) { numTrimming++; } }}computeOomAdjLocked分析1 app.adJseq等于app.completedAdJseq则表示已经计算过2 app.containsCycle为true则会在updateOomAdjLocked中重新调用
// 已经计算过,避免重复计算if (mAdJseq == app.adJseq) { if (app.adJseq == app.completedAdJseq) { // This adjustment has already been computed successfully. return false; } else { // The process is being computed, so there is a cycle. We cannot // rely on this process's state. app.containsCycle = true; return false; }}- 3 空进程处理相关,adj值设置为CACHED_APP_MAX_ADJ返回
// 空进程,直接赋值app.curAdj为ProcessList.CACHED_APP_MAX_ADJif (app.thread == null) { app.adJseq = mAdJseq; app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND); app.setCurProcState(PROCESS_STATE_CACHED_EMPTY); app.curAdj = ProcessList.CACHED_APP_MAX_ADJ; app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ); app.completedAdJseq = app.adJseq; return false;}- 4 persistent apk的maxAdj为PERSISTENT_PROC_ADJ,常见的persistent apk有Phone, systemUI等, 在AndroIDManifest.xml中声明androID:persistent="true"的apk,如果是persistent apk, 将adj值赋值为app.maxAdj, persistent apk在AMS中的systemReady中启动
// present apk将adj值赋值为app.maxAdj if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { app.adjType = "fixed"; app.adJseq = mAdJseq; app.setCurRawAdj(app.maxAdj); app.setHasForegroundActivitIEs(false); app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAulT); app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT); app.systemNoUi = true; if (app == top_APP) { app.systemNoUi = false; app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_top_APP); app.adjType = "pers-top-activity"; } else if (app.hastopUi()) { // sched group/proc state adjustment is below app.systemNoUi = false; app.adjType = "pers-top-ui"; } else if (wpc.hasVisibleActivitIEs()) { app.systemNoUi = false; } app.setCurRawProcState(app.getCurProcState()); app.curAdj = app.maxAdj; app.completedAdJseq = app.adJseq; // if curAdj is less than prevAppAdj, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; }- 5 前台进程判断相关处理
boolean foregroundActivitIEs = false;mTmpbroadcastQueue.clear();// 是否有前台activityif (PROCESS_STATE_CUR_top == PROCESS_STATE_top && app == top_APP) { // The last app on the List is the foreground app. // 顶部运行的进程,即和用户交互的apk adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_top_APP; app.adjType = "top-activity"; foregroundActivitIEs = true; procState = PROCESS_STATE_CUR_top;} else if (app.runningRemoteAnimation) { // 正在执行动画 adj = ProcessList.VISIBLE_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_top_APP; app.adjType = "running-remote-anim"; procState = PROCESS_STATE_CUR_top;} else if (app.getActiveInstrumentation() != null) { // Don't want to kill running instrumentation. // 和测试相关 adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_DEFAulT; app.adjType = "instrumentation"; procState = PROCESS_STATE_FOREGROUND_SERVICE;} else if (mService.isReceivingbroadcastLocked(app, mTmpbroadcastQueue)) { // 正在接收广播 adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = (mTmpbroadcastQueue.contains(mService.mFgbroadcastQueue) || mTmpbroadcastQueue.contains(mService.mCtsFgbroadcastQueue)) ? ProcessList.SCHED_GROUP_DEFAulT : ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "broadcast"; procState = ActivityManager.PROCESS_STATE_RECEIVER;} else if (app.executingServices.size() > 0) { // 正在执行服务回调函数 adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = app.execServicesFg ? ProcessList.SCHED_GROUP_DEFAulT : ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "exec-service"; procState = PROCESS_STATE_SERVICE;} else if (app == top_APP) { adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "top-sleePing"; foregroundActivitIEs = true; procState = PROCESS_STATE_CUR_top;} else { // 暂时设置为cache进程,接下来再进行处理 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; adj = cachedAdj; procState = PROCESS_STATE_CACHED_EMPTY; app.cached = true; app.empty = true; app.adjType = "cch-empty";}- 6 不是前台有activity的进程,但apk中存在有效的activity相关处理
// 不是前台有activity的进程, 但apk中存在有效的activityif (!foregroundActivitIEs && wpc.hasActivitIEs()) { mTmpComputeOomAdjWindowCallback.initialize(app, adj, foregroundActivitIEs, procState, schedGroup, appUID, logUID, PROCESS_STATE_CUR_top); final int minLayer = wpc.computeOomAdjFromActivitIEs( ProcessList.VISIBLE_APP_LAYER_MAX, mTmpComputeOomAdjWindowCallback); adj = mTmpComputeOomAdjWindowCallback.adj; foregroundActivitIEs = mTmpComputeOomAdjWindowCallback.foregroundActivitIEs; procState = mTmpComputeOomAdjWindowCallback.procState; schedGroup = mTmpComputeOomAdjWindowCallback.schedGroup; // 根据layer来确定具体的adj值 if (adj == ProcessList.VISIBLE_APP_ADJ) { adj += minLayer; }}- 7 是否存在前台服务,或者有OverlayUi显示
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) { // 前台服务 if (app.hasForegroundServices()) { adj = ProcessList.PERCEPTIBLE_APP_ADJ; // 使用了位置的前台服务 if (app.hasLocationForegroundServices()) { procState = PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; app.adjType = "fg-service-location"; } else { // 普通前台服务 procState = PROCESS_STATE_FOREGROUND_SERVICE; app.adjType = "fg-service"; } app.cached = false; schedGroup = ProcessList.SCHED_GROUP_DEFAulT; } else if (app.hasOverlayUi()) { // overlay UI. adj = ProcessList.PERCEPTIBLE_APP_ADJ; procState = PROCESS_STATE_important_FOREGROUND; app.cached = false; app.adjType = "has-overlay-ui"; schedGroup = ProcessList.SCHED_GROUP_DEFAulT; }}- 8 前台服务
if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ && (app.lasttopTime + mConstants.top_TO_FGS_GRACE_DURATION > Now || app.setProcState <= PROCESS_STATE_top)) { adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; app.adjType = "fg-service-act";}- 9 重量级进程
// heavy-weight processif(mService.mAtmInternal.isHeavyWeightProcess(app.getwindowProcessController())) { if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { // We don't want to kill the current heavy-weight process. adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.cached = false; app.adjType = "heavy"; } if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; app.adjType = "heavy"; }}- 10 home进程
if (wpc.isHomeProcess()) { if (adj > ProcessList.HOME_APP_ADJ) { // This process is hosting what we currently consIDer to be the // home app, so we don't want to let it go into the background. adj = ProcessList.HOME_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.cached = false; app.adjType = "home"; } if (procState > ActivityManager.PROCESS_STATE_HOME) { procState = ActivityManager.PROCESS_STATE_HOME; app.adjType = "home"; }}- 11 之前启动的进程
if (wpc.isPrevIoUsProcess() && app.hasActivitIEs()) { if (adj > ProcessList.PREVIoUS_APP_ADJ) { adj = ProcessList.PREVIoUS_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.cached = false; app.adjType = "prevIoUs"; } if (procState > PROCESS_STATE_LAST_ACTIVITY) { procState = PROCESS_STATE_LAST_ACTIVITY; app.adjType = "prevIoUs"; }}- 12 设置adj
// 设置原始的adj值app.setCurRawAdj(!cycleReEval ? adj : Math.min(adj, app.getCurRawAdj()));// 设置原始的进程状态app.setCurRawProcState(!cycleReEval ? procState : Math.min(procState, app.getCurRawProcState()));- 13 根据app进程中的服务来确定adj值
// 遍历app进程下的服务for (int is = app.services.size() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_top); is--) { ServiceRecord s = app.services.valueAt(is); if (s.startRequested) { // 通过startService启动过服务 app.hasstartedServices = true; if (procState > PROCESS_STATE_SERVICE) { procState = PROCESS_STATE_SERVICE; app.adjType = "started-services"; } if (app.hasShownUi && !wpc.isHomeProcess()) { if (adj > ProcessList.SERVICE_ADJ) { app.adjType = "cch-started-ui-services"; } } else { // 小于mConstants.MAX_SERVICE_INACTIVITY时间,服务adj值不变 if (Now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { if (adj > ProcessList.SERVICE_ADJ) { adj = ProcessList.SERVICE_ADJ; app.adjType = "started-services"; app.cached = false; } } if (adj > ProcessList.SERVICE_ADJ) { app.adjType = "cch-started-services"; } } } // bindService方式启动 ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections(); for (int conni = serviceConnections.size() - 1; conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_top); conni--) { ArrayList<ConnectionRecord> cList = serviceConnections.valueAt(conni); for (int i = 0; i < cList.size() && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_top); i++) { ConnectionRecord cr = cList.get(i); if (cr.binding.clIEnt == app) { // 绑定的进程是当前进程时,跳过 continue; } if ((cr.flags& Context.BIND_WAIVE_PRIORITY) == 0) { ProcessRecord clIEnt = cr.binding.clIEnt; // 计算clIEnt进程的adj值 computeOomAdjLocked(clIEnt, cachedAdj, top_APP, doingall, Now, cycleReEval); // 根据ProcessRecord的containsCycle和clIEnt的completedAdJseq值来确认身份需要跳过 if (shouldSkipDuetoCycle(app, clIEnt, procState, adj, cycleReEval)) { continue; } // clIEnt进程的adj值 int clIEntAdj = clIEnt.getCurRawAdj(); int clIEntProcState = clIEnt.getCurRawProcState(); String adjType = null; if (adj > clIEntAdj) { if (app.hasShownUi && !wpc.isHomeProcess() && clIEntAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { adjType = "cch-bound-ui-services"; } } else { int newAdj; // 根据flag和clIEnt的adj值来确认newAdj值 if ((cr.flags&(Context.BIND_ABOVE_CLIENT |Context.BIND_important)) != 0) { if (clIEntAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) { newAdj = clIEntAdj; } else { // make this service persistent newAdj = ProcessList.PERSISTENT_SERVICE_ADJ; schedGroup = ProcessList.SCHED_GROUP_DEFAulT; procState = ActivityManager.PROCESS_STATE_PERSISTENT; cr.trackProcState(procState, mAdJseq, Now); trackedProcState = true; } } else if ((cr.flags & Context.BIND_NOT_PERCEPTIBLE) != 0 && clIEntAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ; } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 && clIEntAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { newAdj = ProcessList.PERCEPTIBLE_APP_ADJ; } else if (clIEntAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { newAdj = clIEntAdj; } else { if (adj > ProcessList.VISIBLE_APP_ADJ) { // Todo: Is this too limiting for apps bound from top? newAdj = Math.max(clIEntAdj, ProcessList.VISIBLE_APP_ADJ); } else { newAdj = adj; } } if (!clIEnt.cached) { app.cached = false; } // 从clIEnt进程中选择一个最小的adj值来作为当前进程的adj值 if (adj > newAdj) { adj = newAdj; app.setCurRawAdj(adj); adjType = "service"; } } } } } }}- 14 根据app进程中的ProvIDer来确定adj值
// 遍历当前进程下的ProvIDerfor (int provi = app.pubProvIDers.size() - 1; provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_top); provi--) { ContentProvIDerRecord cpr = app.pubProvIDers.valueAt(provi); for (int i = cpr.connections.size() - 1; i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_top); i--) { ContentProvIDerConnection conn = cpr.connections.get(i); ProcessRecord clIEnt = conn.clIEnt; if (clIEnt == app) { // 绑定的进程是当前进程时,跳过 continue; } // 计算clIEnt进程的adj值 computeOomAdjLocked(clIEnt, cachedAdj, top_APP, doingall, Now, cycleReEval); // 是否需要跳过当前clIEnt进程 if (shouldSkipDuetoCycle(app, clIEnt, procState, adj, cycleReEval)) { continue; } // 获取clIEnt进程的adj值 int clIEntAdj = clIEnt.getCurRawAdj(); int clIEntProcState = clIEnt.getCurRawProcState(); if (clIEntProcState >= PROCESS_STATE_CACHED_ACTIVITY) { clIEntProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if (adj > clIEntAdj) { if (app.hasShownUi && !wpc.isHomeProcess() && clIEntAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { adjType = "ccH-ui-provIDer"; } else { //选取clIEntAdj大的进程为当前进程的adj,adj值越大,越容易被杀 adj = clIEntAdj > ProcessList.FOREGROUND_APP_ADJ ? clIEntAdj : ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); adjType = "provIDer"; } app.cached &= clIEnt.cached; } }- 15 如果有外部程序正在处理, 不能把adj值变大
if (cpr.hasExternalProcessHandles()) { if (adj > ProcessList.FOREGROUND_APP_ADJ) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); schedGroup = ProcessList.SCHED_GROUP_DEFAulT; app.cached = false; app.adjType = "ext-provIDer"; app.adjTarget = cpr.name; } if (procState > PROCESS_STATE_important_FOREGROUND) { procState = PROCESS_STATE_important_FOREGROUND; app.setCurRawProcState(procState); }}- 16 ProvIDer运行时间小于CONTENT_PROVIDER_RETAIN_TIME不将当前app进程的adj值降低
if (app.lastProvIDerTime > 0 && (app.lastProvIDerTime + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > Now) { if (adj > ProcessList.PREVIoUS_APP_ADJ) { // 在mConstants.CONTENT_PROVIDER_RETAIN_TIME时间内不降低当前ProvIDer的进程优先级 adj = ProcessList.PREVIoUS_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.cached = false; app.adjType = "recent-provIDer"; } if (procState > PROCESS_STATE_LAST_ACTIVITY) { procState = PROCESS_STATE_LAST_ACTIVITY; app.adjType = "recent-provIDer"; }}- 17 服务达到一定数量后,为了不影响性能的情况, 将三分之一的服务划分为A类,3分之二划分为B类服务,A类服务具有更高的优先级,更不容易被杀
if (adj == ProcessList.SERVICE_ADJ) { if (doingall) { // A服务进程数是否超过了整个服务的3分之一,是则归为B类服务 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); mNewNumServiceProcs++; if (!app.serviceb) { if (mService.mLastMemoryLevel > Processstats.ADJ_MEM_FACTOR_norMAL && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { // B服务 app.serviceHighRam = true; app.serviceb = true; } else { // A服务 mNewNumAServiceProcs++; } } else { app.serviceHighRam = false; } } if (app.serviceb) { // 将adj值设置为B类的adj值 adj = ProcessList.SERVICE_B_ADJ; } // 设置原始的adj值 app.setCurRawAdj(adj); // 确保adj的值在合理的范围内 if (adj > app.maxAdj) { adj = app.maxAdj; if (app.maxAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { schedGroup = ProcessList.SCHED_GROUP_DEFAulT; } } // 调整adj的值,复制给app.curAdj app.curAdj = app.modifyRawOomAdj(adj); app.setCurrentSchedulingGroup(schedGroup); app.setCurProcState(procState); app.setCurRawProcState(procState); app.setHasForegroundActivitIEs(foregroundActivitIEs); // 计算完成标识 app.completedAdJseq = mAdJseq; return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;}applyOomAdjLocked分析1 1设置进程的adj值// 1设置进程的adj值if (app.curAdj != app.setAdj) { ProcessList.setoomAdj(app.pID, app.uID, app.curAdj); app.setAdj = app.curAdj; app.verifIEdAdj = ProcessList.INVALID_ADJ;}- 2 mProcessGroupHandler的定义
mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup"); final int pID = msg.arg1; final int group = msg.arg2; // 设置进程组 setProcessGroup(pID, group);});- 3 设置进程组和线程组
int oldSchedGroup = app.setSchedGroup;app.setSchedGroup = curSchedGroup;if (app.waitingToKill != null && app.curReceivers.isEmpty() && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) { // 需要kill的进程还没有被kill,现在kill掉 app.kill(app.waitingToKill, true); success = false;} else { int processGroup; switch (curSchedGroup) { case ProcessList.SCHED_GROUP_BACKGROUND: processGroup = THREAD_GROUP_BG_NONINteraCTIVE; 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; } // 设置对应的进程组 mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage( 0 /* unused */, app.pID, processGroup)); try { if (curSchedGroup == ProcessList.SCHED_GROUP_top_APP) { if (oldSchedGroup != ProcessList.SCHED_GROUP_top_APP) { app.getwindowProcessController().ontopProcChanged(); // 设置线程优先级 if (mService.mUseFifoUiScheduling) { // Switch UI pipeline for app to SCHED_FIFO app.savedPriority = Process.getThreadPriority(app.pID); mService.scheduleAsFifoPriority(app.pID, /* suppressLogs */true); if (app.renderThreadTID != 0) { mService.scheduleAsFifoPriority(app.renderThreadTID, /* suppressLogs */true); } } else { // 设置线程优先级 setThreadPriority(app.pID, top_APP_PRIORITY_BOOST); if (app.renderThreadTID != 0) { try { // 设置线程优先级 setThreadPriority(app.renderThreadTID, top_APP_PRIORITY_BOOST); } catch (IllegalArgumentException e) { // thread dIEd, ignore } } } } } }}- 4 通知UsageStats状态变化
if (app.setProcState != app.getCurProcState()) { boolean setimportant = app.setProcState < PROCESS_STATE_SERVICE; boolean curimportant = app.getCurProcState() < PROCESS_STATE_SERVICE; if (setimportant && !curimportant) { // This app is no longer something we consIDer important enough to allow to use // arbitrary amounts of battery power. Note its current cpu time to later kNow to // kill it if it is not behaving well. app.setWhenUnimportant(Now); app.lastcpuTime = 0; } // 通知UsageStats状态变化 maybeUpdateUsageStatsLocked(app, NowElapsed);}uID
用户ID,每个不同的应用程序都有一个uID,uID是你安装应用程序时系统赋予的,是不变的,卸载重新安装有可能会变
pID进程ID
tID线程ID
AndroID中设置进程或线程API,通过使用linux的sched_setscheduler,setpriority函数和 *** 作CGroup文件节点来设置线程优先级和设置调度策略
设置线程优先级Process.setThreadPriority(int tID, int priority)Process.setThreadPriority(int priority)设置线程组Process.setThreadGroup(int tID, int group)设置进程组Process.setProcessGroup(int pID, int group)设置线程调度器Process.setThreadScheduler(int tID, int policy, int priority)线程优先级// 应用的默认优先级public static final int THREAD_PRIORITY_DEFAulT = 0;// 线程的最低优先级public static final int THREAD_PRIORITY_LOWEST = 19;// 后台线程的默认优先级public static final int THREAD_PRIORITY_BACKGROUND = 10;// 前台进程的优先级public static final int THREAD_PRIORITY_FOREGROUND = -2;// 显示功能的优先级public static final int THREAD_PRIORITY_disPLAY = -4;// 紧急显示功能的优先级public static final int THREAD_PRIORITY_URGENT_disPLAY = -8;// 视频线程默认优先级public static final int THREAD_PRIORITY_VIDEO = -10;// 音频线程默认优先级public static final int THREAD_PRIORITY_AUdio = -16;// 紧急音频线程默认优先级public static final int THREAD_PRIORITY_URGENT_AUdio = -19;线程组对应sched_policy.h中的SchedPolicy
// 默认线程组public static final int THREAD_GROUP_DEFAulT = -1;// 后台非交互组public static final int THREAD_GROUP_BG_NONINteraCTIVE = 0;// 前台线程组private static final int THREAD_GROUP_FOREGROUND = 1;// 系统组public static final int THREAD_GROUP_SYstem = 2;// 音频应用程序组public static final int THREAD_GROUP_AUdio_APP = 3;// 系统音频应用程序组public static final int THREAD_GROUP_AUdio_SYS = 4;// 头等app组public static final int THREAD_GROUP_top_APP = 5;// phone等通讯app组public static final int THREAD_GROUP_RT_APP = 6;调度策略// 默认调度策略public static final int SCHED_OTHER = 0;// FIFO调度策略public static final int SCHED_FIFO = 1;// RR调度策略public static final int SCHED_RR = 2;// 批调度策略public static final int SCHED_BATCH = 3;// IDle调度策略public static final int SCHED_IDLE = 5;linux系统API设置调度器int sched_setscheduler(pID_t pID, int policy, const struct sched_param *param);policy: SCHED_OTHER SCHED_BATCH SCHED_IDLE SCHED_FIFO SCHED_RRlinux系统API设置线程或进程优先级int setpriority(int which, int who, int prio);which: PRIO_PROCESS PRIO_PGRP PRIO_USERcgroupscgroups,其名称源自控制组群(control groups)的简写,是linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如cpu、内存、磁盘输入输出等)
Cgroups提供了以下功能:
set_sched_policy和set_cpuset_policy通过 *** 作Cgroups文件节点以达到设置优先级,限制进程cpu资源的目的
int set_cpuset_policy(int tID, SchedPolicy policy);int set_sched_policy(int tID, SchedPolicy policy);@H_889_403@/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/androID/os/Process.java */typedef enum { SP_DEFAulT = -1, SP_BACKGROUND = 0, SP_FOREGROUND = 1, SP_SYstem = 2, // can't be used with set_sched_policy() SP_AUdio_APP = 3, SP_AUdio_SYS = 4, SP_top_APP = 5, SP_RT_APP = 6, SP_RESTRICTED = 7, SP_CNT, SP_MAX = SP_CNT - 1, SP_SYstem_DEFAulT = SP_FOREGROUND,} SchedPolicy;cgroups.Json部分节点如下{ "Cgroups": [ { "Controller": "cpu", "Path": "/dev/cpuctl", "Mode": "0755", "UID": "system", "GID": "system" }, { "Controller": "cpuset", "Path": "/dev/cpuset", "Mode": "0755", "UID": "system", "GID": "system" }, { "Controller": "memory", "Path": "/dev/memcg", "Mode": "0700", "UID": "root", "GID": "system" }, ]}https://www.jianshu.com/p/0501bc2bbe7c
https://www.jianshu.com/p/4ee14aa23f07?from=singlemessage
https://baike.baidu.com/item/Cgroup/4988200?fr=aladdin
http://gityuan.com/2018/05/19/android-process-adj/
http://gityuan.com/2016/08/07/android-adj/
以上是内存溢出为你收集整理的Android adj相关简介介绍全部内容,希望文章能够帮你解决Android adj相关简介介绍所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)