分析下oom kill的条件
时间: 2024-11-27 16:19:44 浏览: 15
在Android系统中,当内存不足(Out-of-Memory, OOM)时,系统会根据进程的重要性和状态来决定哪些进程应该被终止以释放内存。以下是关于OOM Kill的一些关键条件和逻辑:
### 进程优先级分类
1. **前台进程**:当前与用户交互的应用或服务。
2. **可见进程**:虽然不在前台,但仍然对用户可见的进程(如显示通知栏)。
3. **服务进程**:正在运行重要服务的进程。
4. **缓存进程**:不再与用户直接交互但仍可能需要快速恢复的进程。
5. **空闲进程**:最不重要的进程,通常会被最先杀死。
### 关键代码段分析
1. **前台进程保护**
```java
if (app == topApp) {
adj = FOREGROUND_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("top-sleeping");
}
```
如果应用是当前的顶层应用,则将其调整为前台进程,并设置调度组为后台。
2. **广播接收器保护**
```java
if (state.getCachedIsReceivingBroadcast(mTmpSchedGroup)) {
adj = FOREGROUND_APP_ADJ;
schedGroup = mTmpSchedGroup[0];
state.setAdjType("broadcast");
procState = ActivityManager.PROCESS_STATE_RECEIVER;
}
```
正在接收广播的进程被视为前台进程,以防止其被杀。
3. **服务执行保护**
```java
if (psr.numberOfExecutingServices() > 0) {
adj = FOREGROUND_APP_ADJ;
schedGroup = psr.shouldExecServicesFg() ? SCHED_GROUP_DEFAULT : SCHED_GROUP_BACKGROUND;
state.setAdjType("exec-service");
procState = PROCESS_STATE_SERVICE;
}
```
正在执行服务回调的进程也被视为前台进程。
4. **备份保护**
```java
final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId);
if (backupTarget != null && app == backupTarget.app) {
if (adj > BACKUP_APP_ADJ) {
adj = BACKUP_APP_ADJ;
if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
}
}
}
```
正在进行备份的进程也会受到保护,避免被杀。
5. **缓存进程降级**
```java
if (procState >= PROCESS_STATE_LAST_ACTIVITY && state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY && (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) <= now) {
procState = PROCESS_STATE_LAST_ACTIVITY;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("previous-expired");
adj = CACHED_APP_MIN_ADJ;
}
```
长时间未使用的活动进程会被降级为缓存进程。
### 总结
- **前台进程**:最高优先级,几乎不会被杀死。
- **可见进程**:次高优先级,一般也不会被杀死。
- **服务进程**:较高优先级,但在某些情况下可能会被杀死。
- **缓存进程**:较低优先级,当内存紧张时会被考虑杀死。
- **空闲进程**:最低优先级,最容易被杀死。
这些条件和逻辑确保了系统的稳定性和用户体验,同时有效管理有限的内存资源。
阅读全文