Low Memory Killer(一)- android源码分析

标签: Low_Memory_Killer 低内存管理机制 系统内存管理


Low Memory Killer

Android 系统中运行的APP退出到后台时并不会真正杀死这个进程,而是将其缓存起来,以便下次能快速启用(热启动)。在系统内存不足情况下,系统会依据Low Memory Killer机制来杀死进程;

Low Memory Killer 基本原理

所有进程都是从zygote孵化出来的,记录在AMS中mLruProcesses列表中,由AMS统一管理,AMS中会根据进程的状态更新进程对应的oom_adj值,这个值会通过文件传递到kernel中,kernel有个低内存回收机制,在内存达到一定的阀值时会触发清理oom_adj值高的进程腾出更多内存空间

##Low Memory Killer 实现方案
先看android手机中的俩个文件
/sys/module/lowmemorykiller/parameters/minfree //文件中每一个数字代表一个内存级别

bullhead:/ # cat /sys/module/lowmemorykiller/parameters/minfree //文件中每一个数字代表一个内存级别
18432,23040,27648,32256,55296,80640

cat /sys/module/lowmemorykiller/parameters/adj //文件中每一个数字代表一个进程优先级级别

bullhead:/ # cat /sys/module/lowmemorykiller/parameters/adj //文件中每一个数字代表一个进程优先级级别
0,100,200,300,900,906

当系统剩余内存低于80640的时候,系统会杀死adj>=906级别的进程
当系统剩余内存低于55296的时候,系统会杀死adj>=900级别的进程
当系统剩余内存低于32256的时候,系统会杀死adj>=300级别的进程
当系统剩余内存低于27648的时候,系统会杀死adj>=200级别的进程
当系统剩余内存低于23040的时候,系统会杀死adj>=100级别的进程

对于应用进程来说,应用进程自身也有adj,应用进程自身adj由AMS负责更新;

ADJ 调整算法

ActivityManagerService 中三个核心方法:

updateOomAdjLocked:更新adj,当目标进程为空,或者被杀则返回false;否则返回true;
computeOomAdjLocked:计算adj,返回计算后RawAdj值;
applyOomAdjLocked:应用adj,当需要杀掉目标进程则返回false;否则返回true。

    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord TOP_APP, boolean doingAll, long now) {
        if (app.thread == null) {
            return false;
        }

        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);

        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
    }

ADJ更新的地方

即调用updateOomAdjLocked方法的地方

Activity
  • ActivityStackSupervisor.realStartActivityLocked() //启动Activity
  • ActivityStack.resumeTopActivityInnerLocked //恢复栈顶Activity
  • ActivityStack.finishSubActivityLocked //finish掉上一个Activity
  • ActivityStack.finishVoiceTask //
  • ActivityStack.finishCurrentActivityLocked //结束当前Activity
  • ActivityStack.destroyActivityLocked //摧毁当前Activity
Service
  • ActiveServices.bindServiceLocked //绑定服务(只更新当前app)
  • ActiveServices.unbindServiceLocked //解绑服务 (只更新当前app)
  • ActiveServices.realStartServiceLocked //启动服务
  • ActiveServices.sendServiceArgsLocked //在bringup或则cleanup服务过程调用(只更新当前app)
  • ActiveServices.bringDownServiceLocked //结束服务 (只更新当前app)
  • ActiveServices.removeConnectionLocked //清除掉此进程的所有服务连接
  • ActiveServices.serviceDoneExecutingLocked //进程服务出现异常(ANR或其他异常),移除timeout消息
广播
  • BroadcastQueue.processCurBroadcastLocked //处理当前广播
  • BroadcastQueue.deliverToRegisteredReceiverLocked //分发已注册的广播 (只更新当前app)
  • BroadcastQueue.processNextBroadcast //处理下一个广播
Process
  • ActivityManagerService.setSystemProcess //创建并设置系统进程
  • ActivityManagerService.appDiedLocked //进程死亡
  • ActivityManagerService.killAllBackgroundProcesses //杀死所有后台进程.即(ADJ>900或removed=true的普通进程)
  • ActivityManagerService.killPackageProcessesLocked //以包名的形式 杀掉相关进程;
  • ActivityManagerService.attachApplicationLocked //进程创建后attach到system_server的过程;
  • ActivityManagerService.importanceTokenDied // 重要进程死亡
  • ActivityManagerService.setProcessImportant//例如Toast弹出过程,设置进程优先级
  • ActivityManagerService.getContentProviderImpl //获取provider (只更新当前app)
  • ActivityManagerService.removeContentProvider // 移除provider
  • ActivityManagerService.publishContentProviders //发布provider (只更新当前app)
  • ActivityManagerService.removeContentProviderExternalUnchecked
  • ActivityManagerService.publishContentProviders //发布provider (只更新当前app)
  • ActivityManagerService.addAppLocked // 创建persistent进程
  • ActivityManagerService.updateSleepIfNeededLocked //进程休眠相关
  • ActivityManagerService.setHasTopUi //
  • ActivityManagerService.bindBackupAgent //
  • ActivityManagerService.unbindBackupAgent //
  • ActivityManagerService.updateProcessForegroundLocked //将app从前台进程移除
  • ActivityManagerService.setAppIdTempWhitelistStateLocked //
  • ActivityManagerService.setUidTempWhitelistStateLocked //
  • ActivityManagerService.trimApplications //清除没有使用app
  • ActivityManagerService.setHasOverlayUi //

以上就是Low Memory Killer 调用地方和算法框架;下篇文章讲解Low Memory Killer如何将ADJ参数传递到底层kernel,kernel如何进行内存回收

<think>好的,用户想了解关于Androidlowmemorykiller内存管理以及如何调整参数,特别是提到了adj值为1001、file_cache为225528、free内存34551的情况。我需要先理清lowmemorykiller的基本机制,然后结合用户提供的参数进行分析。 首先,根据引用[1],lowmemorykiller通过minfree和adj参数来管理内存。minfree定义了不同内存阈值,adj对应进程的优先级,当内存低于某个minfree值时,会杀掉对应adj或更高adj的进程。用户提供的adj是1001,但通常adj的范围是0到906,如引用[3]中的例子adj是0,100,200,300,900,906。这里可能存在疑问,用户的adj值1001是否超出了常规范围?需要确认是否可能或者是否存在错误。 然后,用户提到file_cache为225528和free内存34551,单位应该是KB吧?需要说明这些数值的意义。file_cache可能指系统缓存,而free是剩余内存。当free降到某个minfree阈值时,lowmemorykiller会被触发。用户可能想知道如何根据当前内存状态调整minfree和adj参数,以防止特定进程被杀死,比如引用[2]中提到的应用保活。 接下来,需要解释参数调整方法。比如修改/sys/module/lowmemorykiller/parameters下的minfree和adj文件,但需要注意参数的数量匹配。同时,引用[2]提到在lmkd.cpp中修改逻辑,可能涉及白名单机制,防止某些app被杀。这可能适用于高级用户或系统开发者。 用户的问题可能还涉及如何根据当前内存情况调整参数,比如adj设为1001是否有效,是否需要扩展adj的范围,或者调整minfree的阈值以适应更高adj值。此外,需要提醒用户修改这些参数的风险,比如系统不稳定或功耗增加。 最后,生成相关问题时,需要考虑用户可能的后续疑问,比如如何监控lowmemorykiller行为,或者在不同Android版本中的差异,以及保活策略的其他方法。</think>### Lowmemorykiller 内存管理机制与参数调整方法 #### Lowmemorykiller 内存管理原理 LowmemorykillerAndroid 系统中用于在内存不足时主动终止低优先级进程的机制。其核心参数包括: 1. **adj 值**:表示进程优先级,数值越大优先级越低(越容易被终止)[^1]。 2. **minfree 值**:定义内存阈值,单位为页(通常 1 页=4KB)[^1]。例如: ```bash $ adb shell cat /sys/module/lowmemorykiller/parameters/minfree 18432,23040,27648,32256,55296,80640 # 对应内存级别 72MB,90MB,108MB,126MB,216MB,315MB ``` 3. **触发规则**:当系统剩余内存(`free`)低于某个 `minfree` 阈值时,终止对应 `adj` 或更高值的进程[^1]。 #### 二、参数解析与调整方法 针对您提到的参数组合 `adj:1001`、`file_cache:225528`、`free:34551`: 1. **adj 值异常分析** - 常规 `adj` 范围是 `0~906`(如引用[3]示例),`1001` 可能表示自定义扩展的优先级层级,但需确认系统是否支持该范围。 - **调整建议**:若需保留进程,应设置更低的 `adj` 值(如 `<100`),并确保与 `minfree` 参数数量匹配。 2. **内存状态解读** - `file_cache:225528`:系统缓存占用的内存(约 881MB) - `free:34551`:可用内存约 135MB(34551×4KB) - **判断逻辑**:若当前 `minfree` 阈值包含 `135MB` 级别,则会触发对应 `adj` 层级的进程终止。 3. **参数调整步骤** ```bash # 修改 adj 和 minfree(需 root 权限) echo "0,100,200,300,900,906,1001" > /sys/module/lowmemorykiller/parameters/adj echo "18432,23040,27648,32256,55296,80640,92160" > /sys/module/lowmemorykiller/parameters/minfree ``` - 需保证 `adj` 与 `minfree` 参数数量- 新增 `92160`(360MB)对应 `adj:1001`,表示当内存低于 360MB 时才会终止该层级进程 #### 三、进程保活高级方法(引用[2]) 1. **修改 lmkd 源码** 在 `/system/memory/lmkd/lmkd.cpp` 中添加进程白名单,绕过终止逻辑: ```cpp static bool is_protected(const char* process_name) { const char* protected_apps[] = {"com.example.app"}; for (auto& app : protected_apps) { if (strcmp(process_name, app) == 0) return true; } return false; } ``` 2. **调整 OOM_SCORE_ADJ** 通过修改进程的 OOM 评分实现保活: ```bash echo -1000 > /proc/<pid>/oom_score_adj # 最低优先级(最不易被终止) ``` #### 四、监控与验证 1. **实时内存状态** ```bash adb shell dumpsys meminfo | grep "Free RAM" ``` 2. **进程终止日志** ```bash adb logcat | grep "lowmemorykiller" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值