admin管理员组文章数量:1558098
文章目录
- 1、简介
- 2、具体分析
1、简介
我们在运行apk 的时候有时进程会被杀死掉,看log 一般出现如此:
ActivityManager: Killing 19893:com.xxx.xxx/u0a106 (adj 500): excessive cpu 7180 during 300080 dur=42644246 limit=2
ActivityManager: Killing 22598:com.xxx.xxx/u0a106 (adj 500): excessive cpu 21890 during 300019 dur=45344791 limit=2
ActivityManager: Killing 31530:com.xxx.xxx/u0a106 (adj 500): excessive cpu 19230 during 300017 dur=31239455 limit=2
ActivityManager: Killing 22598:com.xxx.xxx/u0a106 (adj 500): excessive cpu 21890 during 300019 dur=45344791 limit=2
这其实是Android 本身的一种节省资源的机制。
2、具体分析
比如在Android 8.1 上 AMS 每 5分钟(基于 Android 8.1源码) 检查一下异常耗电情况:
final void checkExcessivePowerUsageLocked() {
updateCpuStatsNow();
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
boolean doCpuKills = true;
if (mLastPowerCheckUptime == 0) {
doCpuKills = false;
}
final long curUptime = SystemClock.uptimeMillis();//从开机到现在的毫秒数,不包括睡眠的时间
final long uptimeSince = curUptime - mLastPowerCheckUptime;//距上次检查的时间间隔
mLastPowerCheckUptime = curUptime;
int i = mLruProcesses.size();
while (i > 0) {
i--;
ProcessRecord app = mLruProcesses.get(i);
if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
if (app.lastCpuTime <= 0) {
continue;
}
long cputimeUsed = app.curCpuTime - app.lastCpuTime;//检查周期内进程CPU使用时长
if (DEBUG_POWER) {
StringBuilder sb = new StringBuilder(128);
sb.append("CPU for ");
app.toShortString(sb);
sb.append(": over ");
TimeUtils.formatDuration(uptimeSince, sb);
sb.append(" used ");
TimeUtils.formatDuration(cputimeUsed, sb);
sb.append(" (");
sb.append((cputimeUsed*100)/uptimeSince);
sb.append("%)");
Slog.i(TAG_POWER, sb.toString());
}
//随着应用退到后台的时间越来越长,进程被允许使用的CPU占比越来越小
// If the process has used too much CPU over the last duration, the
// user probably doesn't want this, so kill!
if (doCpuKills && uptimeSince > 0) {
// What is the limit for this process?
int cpuLimit;
long checkDur = curUptime - app.whenUnimportant;
if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;//25
} else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
|| app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;//25
} else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;//10
} else {
cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;//2
}
if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
synchronized (stats) {
stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
uptimeSince, cputimeUsed);
}
app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
+ " dur=" + checkDur + " limit=" + cpuLimit, true);
app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
}
}
app.lastCpuTime = app.curCpuTime;
}
}
}
随着应用退到后台的时间越来越长,进程被允许使用的CPU占比越来越小:
这个占比的计算方式是:
rate = cputimeUsed*100/uptimeSince 一个检查周期内CPU的使用时长 / 检查周期时长
从上面的log看 是在 Xxx进程退到后台15分钟以后,使用CPU占比超过 2% 触发的。
譬如说进程退到后台15分钟后,在某次检查中,发现5分钟内CPU处于活动状态的时间是 100s, 而该进程占用CPU的时长如果超过 2s (100s * 2% ), 就会触发 杀进程机制。
解决方法 请看文章:
熄屏状态 cpu限制 导致应用退出
文章参考:
AMS checkExcessivePowerUsageLocked 杀进程分析
https://www.jianshu/p/ee027ed53724
通过log中的kill reson来定位应用是被谁杀掉的
https://blog.csdn/amlinsan/article/details/72963969
本文标签: excessiveCPUpidActivityManagerkilling
版权声明:本文标题:ActivityManager: Killing*pid + 包名*: excessive cpu 21890 during 300019 dur=45344791 limit=2 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1727308026a1107532.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论