当前位置: 首页 > news >正文

Lmkd查杀功能的详细步骤

LMKD(Low Memory Killer Daemon)是 Android 系统中负责监控内存压力并在内存不足时终止进程以释放内存的关键守护进程。其查杀功能涉及内存压力监测、查杀条件判断和目标进程选择等步骤。下面这张图清晰地展示了 LMKD 的核心工作流程:

一.详细查杀步骤

1. 内存压力监控

LMKD 通过以下一种或多种机制来感知系统内存压力:

  • PSI(Pressure Stall Information)监控(Android 10及以上推荐):LMKD 订阅内核的 PSI 事件,监控因内存不足导致的任务执行延迟。当部分停滞(如 ro.lmk.psi_partial_stall_ms,默认70ms)或完全停滞(如 ro.lmk.psi_complete_stall_ms,默认700ms)的阈值被突破时,即判定为内存压力事件。
  • Vmpressure 信号:监听内核生成的 vmpressure 事件,其包含低(low)、中(medium)、高(critical)等压力等级。LMKD 会根据这些等级初步判断压力程度。
  • Zone Watermarks(内存区域水位线):通过解析 /proc/zoneinfo/proc/meminfo,计算系统的内存水位线(WMARK_LOW, WMARK_MIN 等)。当可用内存低于特定水位时触发相应操作。
2. 判断查杀条件与确定 min_score_adj

当监测到内存压力事件后,LMKD 并非立即查杀,而是需要综合判断:

  • 压力等级与阈值:系统将当前监测到的压力水平(如 PSI 指标、vmpressure 等级或 zone watermark 水平)与预设的阈值进行比较。例如,在 PSI 机制下,当 avg10(10秒内的平均压力)超过 psi_partial_stall_ms 设定的阈值时,会触发查杀。
  • 其他因素:LMKD 还会考虑内存抖动(thrashing)程度、交换空间(swap)使用情况等因素,以防误杀或确保查杀有效性。
  • 确定 min_score_adj:根据上述判断,LMKD 会确定一个本次查杀的最低 oom_score_adj 阈值(min_score_adj)。只有 oom_score_adj 值大于或等于此阈值的进程才可能被终止。通常,压力越大,min_score_adj 值设定得越小(即允许查杀更重要的进程)。例如,在 vmpressure 机制中,ro.lmk.critical 属性可设置为 0,表示在关键压力下任何进程(包括前台应用)都可能被终止。
3. 选择并终止目标进程

LMKD 按照进程的 oom_score_adj 值(从高到低,即优先级从低到高)来筛选目标。

  • 选择策略
    • 终止最重进程:若系统属性 ro.lmk.kill_heaviest_tasktrue,LMKD 会在符合条件的 oom_score_j 等级中,选择内存占用(RSS)最大的进程终止。这有助于用最少的杀进程次数释放尽可能多的内存,常用于感知层级的进程(adj <= 200)。
    • 终止链表末尾进程:若上述属性为 false,则选择对应 adj 级别链表末尾的进程(通常是最近被移入该级别的进程)。
  • 遍历与终止:LMKD 从 oom_score_adj 最大值(1000,最低优先级)开始向下遍历,直至 min_score_adj。在遍历过程中,一旦在某个 adj 级别找到了目标进程,便会调用 kill_one_process 函数向其发送 SIGKILL 信号强制终止该进程。LMKD 会评估此次终止释放的内存是否缓解了内存压力。如果压力仍未解除,可能会启动新一轮的查杀流程,并可能调整 min_score_adj

核心配置属性

LMKD 的行为可通过以下系统属性调节,这些属性通常由设备制造商在 build.prop 中配置

属性作用默认值示例
ro.lmk.use_psi是否使用 PSI 监视器(否则使用 vmpressure)true
ro.lmk.psi_partial_stall_ms部分 PSI 失速阈值(毫秒)70
ro.lmk.psi_complete_stall_ms完全 PSI 失速阈值(毫秒)700
ro.lmk.low低压力级别对应的最小 oom_adj 分数1001(通常禁用)
ro.lmk.medium中压力级别对应的最小 oom_adj 分数800(缓存或非核心服务)
ro.lmk.critical关键压力级别对应的最小 oom_adj 分数0(任何进程)
ro.lmk.kill_heaviest_task是否优先杀死最重任务true(最佳决策)或 false(快速决策)
ro.lmk.thrashing_limit_pct内存抖动限制百分比-

主要查杀模式

Android 系统中的 LMKD 主要存在两种实现模式:

  • 用户空间 lmkd(主流):运行在用户空间,利用 PSI 或 vmpressure 进行更精细的内存压力判断,并执行进程终止。这是目前主流的方式。
  • 内核空间 LMK(传统):通过写入 /sys/module/lowmemorykiller/parameters/minfreeadj 来设置内存阈值与 adj 的对应关系。当内存低于阈值时,内核直接终止对应 adj 级别的进程。此方式较粗糙,已逐渐被用户空间 lmkd 取代。

二.如果lmkd查杀到adj 200 的可感知进程,是查杀的太激进了么?为什么一直会查杀的这么狠

当 LMKD 频繁查杀 adj 值为 200 的可感知进程时,这通常表明系统内存资源确实非常紧张,或者当前的查杀策略配置可能过于激进。下面我们来具体分析原因和应对方法。

⚙️ 查杀原因分析:为何会“手狠”

LMKD 决定是否查杀以及查杀哪个进程,主要基于一套阈值规则。如果它频繁对 adj 200 的进程“动手”,通常是以下一个或多个原因造成的:

  1. 内存压力巨大:这是最根本的原因。当系统可用内存持续低于为 adj 200 进程所设定的内存阈值时,LMKD 就会启动查杀。这就像一个水池的水位不断跌破更高的警戒线,说明缺水严重。可能的情况有:

    • 设备物理内存较小,或同时运行了太多消耗内存的应用。
    • 存在内存泄漏,导致可用内存快速减少。
  2. 查杀策略配置:LMKD 的行为可以通过系统属性进行配置。例如,ro.lmk.critical 属性定义了在内存关键压力级别下可被杀死的进程的最低 oom_adj 分数

    。如果这些阈值设置得过于激进(例如,让系统过早地进入“关键压力”状态),就可能导致优先级较高的进程被提前清理。
  3. PSI 监控机制触发:在新版 Android 中,LMKD 使用 PSI(Pressure Stall Information)监控内存压力

    。如果系统因内存不足导致任务执行出现延迟(即“停滞”),并且停滞时间超过了设定的阈值(如 ro.lmk.psi_partial_stall_ms 默认的 70ms),LMKD 就会触发行动。这可能发生在实际可用内存绝对值还不太低,但内存子系统已非常繁忙的时刻。
  4. 选择了“最重”的进程:LMKD 有一个配置项 ro.lmk.kill_heaviest_task。当此选项设置为 true 时,LMKD 会在符合条件的进程中选择内存占用(RSS)最大的那个进行终止

    。如果你的可感知进程(如后台音乐应用)恰好占用了较多内存,即使其 adj 值不是最低的,也可能被优先选中以快速释放大量内存。

🔧 避免查杀的核心策略

首先,我们可以从应用和系统两个层面主动采取措施,降低内存压力触发的概率。

🔍 深入监控内存水位与压力

要全面诊断问题,你需要监控以下几个关键指标,它们能帮你更清晰地看到内存使用的全貌。

1. 查看系统内存水位线

这是理解内核内存回收行为的直接窗口。你可以通过以下命令查看详细数据:

cat /proc/zoneinfo | grep -E "Node|min|low|high" 

怎么看:关注 pages free(剩余页数)与 minlowhigh 这三个水位线的位置关系。如果 pages free 持续在 low 甚至 min 附近徘徊,就说明系统内存压力巨大,LMKD很可能即将行动。单位是内存页,通常一页为4KB。

2. 监控PSI指标

PSI提供了传统水位线之外更精细的压力视角。你可以查看以下文件来获取PSI数据:

cat /proc/pressure/memory 

generic_x86_arm:/ # cat /proc/pressure/memory
some avg10=0.00 avg60=0.00 avg300=0.00 total=3856932
full avg10=0.00 avg60=0.00 avg300=0.00 total=1561696

怎么看:输出中的 avg10 表示过去10秒的平均压力百分比。如果这个值,尤其是 full 指标下的值,持续偏高(例如超过20%),说明有相当一部分任务因为等待内存而处于停滞状态,即使此时绝对剩余内存可能看起来还“够用”。这解释了为何有时LMKD会“提前”行动。

3. 综合评估可用内存

不要只看 free 内存,那会严重低估系统的真实容量。更准确的指标是 Available 内存(在 cat /proc/meminfo 中查看)。

为什么Available 内存 ≈ Free 内存 + 可立即回收的缓存和缓冲区内存。这个值才真正代表系统在不引发严重卡顿的情况下,还能分配多少新内存。

📈 构建完整的监控流程

建议你将这些检查点整合成一个诊断流程:

  1. 常规监控:定期检查 /proc/meminfo 中的 MemAvailable,这是系统内存健康度的晴雨表。
  2. 压力分析:当 MemAvailable 开始显著下降时,去查看 /proc/pressure/memory 的PSI数据,确认是否存在因内存不足导致的性能瓶颈。
  3. 根本原因调查:如果PSI压力也很高,再通过 /proc/zoneinfo 观察具体的水位线情况,并利用 ps 或 top 命令定位是哪些进程占用了大量内存。

首先,理解PSI阈值的作用

这两个参数是LMKD使用PSI(Pressure Stall Information)监控机制的核心:

  • ro.lmk.psi_partial_stall_ms:指的是在1秒的时间窗口内,如果至少有一个任务在内存分配上被阻塞(stall)的时间超过这个毫秒值,就会触发中等(MEDIUM)级别的内存压力事件。默认值通常是70毫秒(高性能设备)或200毫秒(低内存设备)。
  • ro.lmk.psi_complete_stall_ms:指的是在1秒的时间窗口内,如果所有非空闲任务在内存分配上被阻塞的总时间超过这个毫秒值,就会触发关键(CRITICAL)级别的内存压力事件。默认值通常是700毫秒。

简单来说,降低这些阈值会使LMKD对内存压力更敏感,可能更早开始杀进程;提高这些阈值则会使LMKD更“容忍”内存压力,从而减少查杀

基于你的目标是避免查杀过于激进,核心思路是适当提高这两个参数的数值

  1. 确认当前值并提高阈值

    • 首先,通过 getprop 命令查看这些属性的当前值,例如:
adb shell getprop ro.lmk.psi_partial_stall_ms 
adb shell getprop ro.lmk.psi_complete_stall_ms 

建议采用小步渐进的调整方式。例如,先将 ro.lmk.psi_partial_stall_ms 从70毫秒尝试提高到 90-120毫秒,将 ro.lmk.psi_complete_stall_ms 从700毫秒尝试提高到 900-1000毫秒。这可以让LMKD在内存压力持续更长时间后才采取行动。

修改属性值

  • 你需要Root权限才能永久修改这些系统属性。临时修改可以使用 setprop 命令,例如:
adb shell su -c "setprop ro.lmk.psi_partial_stall_ms 100" 

永久修改通常需要修改设备的 build.prop 文件或在 system.prop 文件中添加定义,然后重启设备。

其他相关参数协同调整

单一调整PSI阈值可能不够,可以考虑同步调整以下参数以形成组合策略:

调整参数后,必须密切观察系统行为,避免调整过度导致系统因内存不足(OOM)而崩溃。

  1. 启用LMKD调试日志:设置 ro.lmk.debug 属性为 true,然后使用 adb logcat | grep -i lmkd 查看详细的杀进程日志。关注触发杀进程时的压力级别、被杀进程的adj值以及系统内存状况。
  2. 监控PSI指标:直接查看 /proc/pressure/memory 文件,观察 somefull 指标在 avg10(过去10秒平均值)上的变化。这能帮你直观看到调整后的压力水平。
  3. 监控系统整体内存状态:使用 cat /proc/meminfo 命令,重点关注 MemAvailable 字段,它比 MemFree 更能反映系统的真实可用内存容量。

http://www.dtcms.com/a/487023.html

相关文章:

  • MATLAB多隐含层极限学习机(ML-ELM) - 大数据处理
  • Wireshark 使用教程(从入门到进阶)
  • 成都建网站要多少钱给一个装修公司怎么做网站
  • iis部署网站 错误400大都会app官网下载
  • 内存泄漏与内存溢出
  • 【C++】priority_queue和deque的使用与实现
  • 导航网站cms跨境贸易电子商务服务平台
  • 公司宣传网站制作电子商务网站定制
  • 虚拟机Windows Server IIS部署WebApi Nginx部署Vue
  • LiteLLM:让LLM调用变得简单统一
  • 基于 Flask+Vue+MySQL的研学网站
  • Spring MVC 分布式事务与数据一致性教程
  • Spring MVC练习:留言板
  • 摄影设计网站wordpress下载及使用
  • 厦门网站建设开发公司无锡建网站电话
  • 什么是站群服务器
  • Linux服务器编程实践27-详解TCP状态转移:从LISTEN到TIME_WAIT的完整路径
  • 网站怎么推广效果好一点呢宁波优化关键词首页排名
  • 门户网站价格天津网站建设基本流程
  • 数据分析-泊松分布
  • 教育类网站开发文档做网站一万
  • 【嵌入式软件】STM32 UART转485通信问题
  • MATLAB离群点检测与删除
  • 星Day-33 基础补充
  • 网站后台换qqwindows7 iis配置 网站
  • 网站推广的最终目的是什么网站建立步骤
  • Apache Paimon:为大规模数据场景打造 “统一存储语言”
  • Hadoop生态核心组件全面解析
  • 考研408《计算机组成原理》复习笔记,第五章(4)——CPU的【硬布线控制器】
  • 01 MySQL数据库基础入门指南