android的oomkiller_Android内存管理篇 - 从updateOomAdjLocked看lowmemorykiller之外的Android进程回收机制...

提起android的进程回收机制,大家所熟知的是Android的lowmemroykiller的机制。当系统可用内存低于某个阀值时,即会杀死这个阀值对应的Adj值的所有应用。但是本篇文章并为是要介绍Lowmemorykiller的机制,而是要搞清楚在未触发Android低杀机制时,Android是否有某种策略对进程进行回收。因为随着硬件成本低降低,各品牌手机低配置也是越来越高,4G及6G内存的手机层出不穷,在这类高内存配置的手机下,按照lowmemorykiller的默认参数来看,低杀出现的概率也小了很多。通过对AMS中的updateOomAdjLocked()方法的分析即可了解Android在lowmemorykiller之外的Android进程回收机制。

那我们按顺序来介绍updateOomAdjLocked方法。首先时初始化一些变量用以后续的操作。TOP_ACT和TOP_APP表示当前处于前台的app(若无app 处于前台则是TASK栈栈顶的应用);根据LRU列表得到当前系统的存在的进程数量N;重置用户组中的进程状态的动作。TOP_ACT,rankTaskLayersIfNeeded方法,mAdjSeq这些变量主要是用于后面方法中会待调用的computateOomAdjLocked()方法,这不是我们本篇的重点,所以不再展开进行详解。

final ActivityRecord TOP_ACT = resumedAppLocked();

final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;

final long now = SystemClock.uptimeMillis();

final long nowElapsed = SystemClock.elapsedRealtime();

final long oldTime = now - ProcessList.MAX_EMPTY_TIME;

final int N = mLruProcesses.size();

...

// Reset state in all uid records.

for (int i=mActiveUids.size()-1; i>=0; i--) {

final UidRecord uidRec = mActiveUids.valueAt(i);

if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,

"Starting update of " + uidRec);

uidRec.reset();

}

mStackSupervisor.rankTaskLayersIfNeeded();

mAdjSeq++;

mNewNumServiceProcs = 0;

mNewNumAServiceProcs = 0;

mProcessLimit表示的是系统允许保留的后台进程和empty进程的总和,初始化为ProcessList.MAX_CACHED_APPS常量,默认为32。Android自身的机制在运行中不会主动修改这个值,但用户可以在“开发者选项”的“后台进程限制”这一项来修改该值。emptyProcessLimit和cachedProcessLimit分别为根据mProcessLimit的值计算出的允许的后台进程和empty进程的最大数量。当mProcessLimit不小于0且不等于1时,后台进程和empty进程和后台进程的数量各占mProcessLimit的一半。 本文讲的后台进程是指cached进程里的非empty的进程,而不包含后台服务进程。

final int emptyProcessLimit;

final int cachedProcessLimit;

if (mProcessLimit <= 0) {

emptyProcessLimit = cachedProcessLimit = 0;

} else if (mProcessLimit == 1) {

emptyProcessLimit = 1;

cachedProcessLimit = 0;

} else {

emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);

cachedProcessLimit = mProcessLimit - emptyProcessLimit;

}

再往下是初始化一些变量的操作,这里要重点注意numSlots所表达的意思。ProcessList.CACHED_APP_MAX_ADJ和Process.CACHED_APP_MIN_ADJ常量系统默认的值分别为906和900,表示的是后台进程和empty进程分配的值是在900至906之间,共有7个值。numSloas计算过程中除以2是因为每个槽配置到进程包含后台进程和empty进程两种,两种进程需用不同adj值表示,所以每个槽包含两个adj值的分配空间,所以需要除以二,计算出来的numSlots值为3。emptyFactor表示每个槽中需要放置几个empty进程,是根据当前empty进程总数决定的,cachedFactor即是表示需要放置几个后台进程到每个槽中。

为便于理解,结合后面代码逻辑举例来讲,比如后台此时有15个cahcedProcess(后台进程)和12个emptyProcess,则会将15/3=5个cachedProcess设置到在第一个槽(可分配900,901这两个oom_adj值)中,oom_adj设置为900;将12/4=4个emptyProcess设置在第一槽,oom_adj值设置为901;然后再设置5个cachedProcess和4个emptyProcess的oom_adj值分别为902和903,即第二个槽。

// Let's determine how many processes we have running vs.

// how many slots we have for background processes; we may want

// to put multiple processes in a slot of there are enough of

// them.

int numSlots = (ProcessList.CACHED_APP_MAX_ADJ

- ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;

int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;

if (numEmptyProcs > cachedProcessLimit) {

// If there are more empty processes than our limit on cached

// processes, then use the cached process limit for the factor.

// This ensures that the really old empty processes get pushed

// down to the bottom, so if we are running low on memory we will

// have a better chance at keeping around more cached processes

// instead of a gazillion empty processes.

numEmptyProcs = cachedProcessLimit;

}

int emptyFactor = numEmptyProcs/numSlots;

if (emptyFactor < 1) emptyFactor = 1;

int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;

if (cachedFactor < 1) cachedFa

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值