Android adj相关简介介绍

Android adj相关简介介绍,第1张

概述Android应用程序主要以activity/service/contentprovider/broadcastrecevier四大组件组成,ActivityManagerService根据四大组件的生命周期函数,以及进程的创建,死亡等来动态调节进程自身的状态,影响进程的CPU占用时间,内存IO等资源分配。进程有两个比较重要的状态值,即adj(定义在P

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;
OomAdjuster

Android10.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_RR
linux系统API设置线程或进程优先级
int setpriority(int which, int who, int prio);which:	PRIO_PROCESS	PRIO_PGRP	PRIO_USER
cgroups

cgroups,其名称源自控制组群(control groups)的简写,是linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如cpu、内存、磁盘输入输出等)


Cgroups提供了以下功能:

1.限制进程组可以使用的资源数量(Resource limiting )2.进程组的优先级控制(Prioritization )3.记录进程组使用的资源数量(Accounting )4.进程组隔离(Isolation)5.进程组控制(Control)libprocessgroup

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相关简介介绍所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1029600.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-23
下一篇2022-05-23

发表评论

登录后才能评论

评论列表(0条)

    保存