java ams 更新oom_adj
时间: 2025-07-23 14:00:23 浏览: 11
<think>首先,用户的问题是:“我想调整Android中AMS的oom_adj值 请问Android AMS update oom_adj configuration”。这涉及到Android的Activity Manager Service (AMS)如何更新oom_adj值。
从系统级指令中,我需要:
- 所有行内数学表达式使用$...$格式。
- 独立公式使用$$...$$格式并单独成段。
- LaTeX语法正确。
- 使用中文回答。
- 生成相关问题。
- 在回答中引用的段落末尾自然地添加引用标识,如[^1]。
用户可见层要求:
- 回答结构清晰,帮助用户逐步解决问题。
- 保证回答真实可靠。
参考提供的引用:
- [^1]: AMS 更新进程优先级:1) AMS.applyOomAdjLocked() 设置进程的adj;2) AMS.updateConfiguration() 更新各个级别的oom_adj信息;3) AMS.cleanUpApplicationRecordLocked() 或 handleAppDiedLocked() 移除进程。
- [^2]: 当AMS第一次接到configuration change时,更新OOM level,lowmemorykiller的lowmem_autodetect_oom_adj_values()被调用。
- [^3]: AMS.updateConfiguration() 调用 updateOomLevels(),向/sys/module/lowmemorykiller/parameters/ 写入minfree和adj信息。
- [^4]: 描述oom_adj到oom_score_adj的转换公式,以及lowmemorykiller如何工作。
- [^5]: 关于Activity启动流程的引用,但可能不直接相关。
用户的问题是关于调整oom_adj值并更新配置。关键是如何通过AMS更新oom_adj配置。
核心步骤:
1. **理解oom_adj**:oom_adj是Android中用于内存管理的值,表示进程的优先级(越低优先级越高,越不容易被杀死)。
2. **AMS如何更新oom_adj**:
- 根据引用[^1],AMS.updateConfiguration() 方法用于更新oom_adj配置。
- 引用[^3] 确认了AMS.updateConfiguration() 调用 updateOomLevels(),写入到/sys/module/lowmemorykiller/parameters/minfree 和 adj。
- 引用[^4] 解释了oom_adj到oom_score_adj的转换。
具体过程:
- AMS.updateConfiguration() 被调用时,它会更新OOM级别。
- 这涉及到写入lowmemorykiller的参数:minfree(内存阈值)和adj(对应的oom_adj值)。
- 例如,minfree文件包含内存阈值列表,adj文件包含对应的oom_adj值。
调整oom_adj值:
- 用户可能想修改默认的oom_adj值或添加自定义值。
- 在Android中,这通常需要修改系统代码或使用特定API。
- 但用户是开发者?可能需要指导如何通过代码调整。
回答结构:
1. **解释oom_adj和AMS的角色**:简要介绍oom_adj和AMS如何管理它。
2. **更新oom_adj配置的机制**:基于引用,描述AMS.updateConfiguration() 的作用。
3. **如何调整值**:提供方法,如修改系统文件或通过代码调用API。
4. **注意事项**:提到权限和风险,因为修改系统文件可能需要root权限。
5. **生成相关问题**:在结尾添加相关问题。
使用中文回答。
在回答中引用段落末尾添加引用标识。例如,解释时提到引用[^1]。
数学表达式:如果有公式,使用LaTeX。例如,引用[^4]中有公式:
- lowmem_oom_adj_to_oom_score_adj 函数:如果oom_adj == OOM_ADJUST_MAX,则oom_score_adj = OOM_SCORE_ADJ_MAX;否则,oom_score_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE。
- OOM_ADJUST_MAX = 15, OOM_SCORE_ADJ_MAX = 1000, OOM_DISABLE = -17.
- 所以,公式:如果 $oom\_adj = 15$,则 $oom\_score\_adj = 1000$;否则,$oom\_score\_adj = \frac{oom\_adj \times 1000}{17}$。
在回答中,如果需要,使用行内格式。
生成相关问题:基于主题,如如何手动设置oom_adj,AMS的其他方法等。
完整回答大纲:
1. 介绍:什么是oom_adj和为什么需要调整。
2. AMS更新oom_adj的机制:重点在AMS.updateConfiguration()。
3. 步骤调整:如何通过代码或文件修改。
4. 注意事项。
5. 相关问题。</think>### 调整Android AMS的oom_adj值配置
在Android系统中,`oom_adj`(Out-Of-Memory Adjustment)值用于表示进程的内存优先级(值越低,优先级越高,越不容易被系统杀死)。Activity Manager Service (AMS) 负责动态管理这些值,以优化内存使用。以下是调整和更新`oom_adj`配置的详细步骤和机制,基于Android框架的实现(以Android 10为例)。
#### 1. **理解oom_adj更新机制**
AMS 通过以下核心方法更新`oom_adj`配置:
- **AMS.updateConfiguration()**:这是关键入口,当系统配置变更(如屏幕旋转、语言切换)或手动触发时,该方法会调用`updateOomLevels()`,更新所有进程的OOM级别。它向Linux内核的lowmemorykiller驱动写入参数,包括:
- `/sys/module/lowmemorykiller/parameters/minfree`:内存阈值列表(单位:page)。
- `/sys/module/lowmemorykiller/parameters/adj`:对应的`oom_adj`值列表。
例如,默认配置可能为 `minfree = "18432,23040,27648,32256,55296,80640"` 和 `adj = "0,100,200,300,900,906"`,表示当可用内存低于18432页时,杀死`oom_adj≥0`的进程[^3]。
- **AMS.applyOomAdjLocked()**:针对单个进程设置`oom_adj`值,通常在进程状态变化(如启动或切到后台)时调用。它会直接修改`/proc/<pid>/oom_score_adj`文件(内核使用的实际值)[^1]。
- **移除进程**:当进程结束时,`AMS.cleanUpApplicationRecordLocked()` 或 `handleAppDiedLocked()` 将其从lmkd(Low Memory Killer Daemon)策略中移除[^1]。
`oom_adj` 到 `oom_score_adj` 的转换使用公式:
$$
\text{oom\_score\_adj} =
\begin{cases}
1000 & \text{if } \text{oom\_adj} = 15 \\
\frac{\text{oom\_adj} \times 1000}{17} & \text{otherwise}
\end{cases}
$$
其中,$OOM\_ADJUST\_MAX = 15$,$OOM\_SCORE\_ADJ\_MAX = 1000$,$OOM\_DISABLE = -17$[^4]。
#### 2. **调整oom_adj值的步骤**
若要手动调整`oom_adj`值,需通过系统级操作(**需要root权限**):
##### 方法一:修改lowmemorykiller参数(直接写入sysfs)
- **步骤**:
1. 获取root权限:`adb root`。
2. 挂载系统分区为可写:`adb remount`。
3. 更新`adj`文件:
```bash
adb shell "echo '0,100,200,250,500,900' > /sys/module/lowmemorykiller/parameters/adj"
```
这里将第三个阈值对应的`oom_adj`从默认300改为250,使该级别进程更容易被杀死。
4. 可选:更新`minfree`以调整内存阈值:
```bash
adb shell "echo '12288,18432,24576,30720,55296,80640' > /sys/module/lowmemorykiller/parameters/minfree"
```
5. 触发AMS更新:发送配置变更广播,强制AMS调用`updateConfiguration()`:
```bash
adb shell am broadcast -a android.intent.action.CONFIGURATION_CHANGED
```
- **注意事项**:修改是临时的(重启后失效),且需确保`adj`和`minfree`数组长度匹配。
##### 方法二:通过AMS代码修改(系统开发者)
如果是AOSP(Android Open Source Project)开发,可在`ActivityManagerService.java`中调整:
- **修改默认值**:编辑`updateOomLevels()`方法,调整`mOomAdj`数组的预设值。
- **自定义进程adj**:在`applyOomAdjLocked()`中,根据进程类型(如`ProcessList.HOME_APP_ADJ`)覆盖`oom_adj`计算逻辑。
- **触发更新**:在代码中调用`updateConfiguration()`,例如响应特定事件:
```java
// 示例:在AMS中手动触发更新
mHandler.post(() -> updateConfiguration());
```
#### 3. **注意事项与风险**
- **权限要求**:写入sysfs或修改AMS代码需要root权限或系统签名权限,普通应用无法直接操作。
- **稳定性风险**:错误配置可能导致系统频繁杀死关键进程(如SystemUI),引发崩溃或ANR(Application Not Responding)。
- **版本兼容性**:不同Android版本中AMS实现可能变化(如Android 12引入Perceptible进程级别),需检查源码适配。
- **调试工具**:使用`adb shell cat /proc/<pid>/oom_score_adj` 验证进程的当前值,或`dumpsys activity oom` 查看系统OOM状态。
#### 4. **底层原理简述**
当AMS调用`updateConfiguration()`时:
1. 计算新`oom_adj`级别并写入sysfs。
2. lmkd守护进程读取参数,更新内核策略。
3. 内核shrinker机制在内存不足时,基于当前`oom_adj`和RSS(Resident Set Size)选择进程杀死[^4]。
例如,系统启动时首次配置变更会触发此流程[^2]。
阅读全文
相关推荐
















