96SEO 2026-05-03 12:56 3
Ru果你曾在手机卡顿、弹窗提示“系统正在回收内存”时惊讶不Yi,那么背后隐藏的“低内存杀手”正悄悄发挥作用。本文把这位无声的守护者从用户空间到内核层面全部拆开来聊,让你一次kan清它的血肉与脾气。

Linux 的 OOM Killer 在系统彻底耗尽可用页帧时才会动手,往往Yi经危及系统稳定。Android 为了在 RAM 仍有余地时就提前“裁员”,引入了geng细腻的 LMKD。它通过监听 PSI压力事件,在不同阈值下挑选合适的进程进行终止,从而把卡顿概率压到Zui低。
关键概念速览
PSI 事件:由 kernel 报告 memory、cpu、io 三类压力;LMKD 只关心 memory。
oom_score_adj:每个进程在 /proc/
minfree & adj 阈值文件:/sys/module/lowmemorykiller/parameters/minfree 与 adj,用来映射 “水位线” 与 “杀进程分数”。
二、从 ActivityManager 到 LMKD:数据流动全景图Android 框架层负责给每个进程算出一个 adj,然后把它们送给用户空间守护进程 lmkd,Zui后由 lmkd 写入 kernel 接口让真正的杀手执行。
ActivityManagerService在组件状态变化时调用 OomAdjuster.applyOomAdjLSP。该函数会检查 ProcessRecord 的当前 adj 与目标 adj 是否一致,Ru果不同就调用下面这段代码向 lmkd 报文:
public static void setOomAdj {
if return;
ByteBuffer buf = ByteBuffer.allocate;
buf.putInt; // 命令标识
buf.putInt;
buf.putInt;
buf.putInt; // 新的 oom_score_adj
writeLmkd; // 把报文塞进 socket
}
写完后AMS 并不会立刻kan到 kill 的结果,而是把职责交给了 LMKD。
2️⃣ ProcessList.remove:当进程死亡时怎么通知 LMKD?当 AMS 检测到某个 pid Yi经不再运行,它会调用 ProcessList.remove,内部同样组装一个报文,只是命令改为 LMK_PROCREMOVE
public static final void remove {
if return;
ByteBuffer buf = ByteBuffer.allocate;
buf.putInt;
buf.putInt;
writeLmkd; // 告诉 lmkd 把 /proc/pid/… 删除
}
3️⃣ Lmkd 与 AMS 的 socket 通讯细节
Lmkd 在 init 阶段打开名为 “lmkd” 的本地 seqpacket socket,随后进入 epoll 循环等待 AMS 发来的报文。收到后由 ctrl_command_handler 按命令类型分流:
LMK_TARGET:
LMK_PROCPRIO:
LMK_PROCREMOVE:
AMS → Lmkd → Kernel → 杀进程 → 回馈日志,这是一条闭环链路。
三、LMKD 内部实现要点 Lmkd 主循环:epoll + event‑driven 模型static void mainloop {
while {
struct epoll_event events;
int ne = epoll_wait(epollfd, events, maxevents,
kill_timeout_ms ? delay : -1);
for {
if
handler_info = events.data.ptr,
handler_info->handler;
}
}
}
Lmkd 用 epoll 同时监听控制 socket、数据 socket 和可Neng出现的 pidfd 通知,实现了“边收边处理”的高效模型。
Lmkd 如何挑选要杀掉的进程?——find_and_kill_processstatic int find_and_kill_process(int min_score_adj,
struct kill_info *ki,
union meminfo *mi,
struct wakeup_info *wi,
struct timespec *tm,
struct psi_data *pd) {
for {
struct proc *p = choose_heaviest ? proc_get_heaviest
: proc_adj_tail;
while {
int freed = kill_one_process(p, min_score_adj,
ki, mi, wi, tm, pd);
if return freed;
p = next_candidate;
}
}
return 0;
}
Lmkd 会遍历从Zui高分数到阈值之间的所有槽位,每次挑出占用Zui大内存的那个,发送 SIGKILL 并统计释放量;Ru果一次不足,则继续向下找。
Lmkd 对 adj 表与 minfree 表的维护逻辑static void cmd_target {
for {
lmk_target t;
lmkd_pack_get_target;
lowmem_minfree = t.minfree;
lowmem_adj = t.oom_adj_score;
// 同步写入 sysfs,以供 kernel 使用
writefilestring("/sys/module/lowmemorykiller/parameters/minfree",
build_minfree_string, true);
writefilestring("/sys/module/lowmemorykiller/parameters/adj",
build_adj_string, true);
}
}
Lkm 向 kernel 暴露两串逗号分隔的数据,一条代表每个水位需要保留多少空闲页,一条对应每条水位所Neng接受的Zui高 adj 分数。
四、完整工作流演练:一次真实触发过程示例
Psi 报警:Kernal 检测 memory pressure 超过第 2 条 minfree 水位,将 PSI 信息推送至用户空间事件队列。
Lmkd 收到通知:Mainloop 中对应 handler 调用 suspend_polling, 随后执行 alert_memory_pressure。此时 Lmkd Yi经知道当前需要达到哪个阈值。
Select victim:find_and_kill_process) 按照当前阈值遍历 adj 槽位,从Zui高分开始尝试 kill;第一次成功后返回释放字节数,Ru果仍不足则继续循环。
SIGKILL 发射:KILL_ONE_PROCESS 调用 `kill` 并记录 kill 信息至 stats;若使用 pidfd,则会等待子线程确认Yi死亡。
Ams 收获反馈:Lmkd 将 kill 消息写回 AMS,通过 LkmStatsReporter 打印日志,如 “Kill occurred: pid=12345 uid=10086”.
Ams geng新状态:Ams 在收到 kill 回执后会geng新相应 ProcessRecord 的 state 为 KILLED,并将其从 LRU 列表中剔除,完成一次完整回收循环。
五、调参指南:怎样让 LMKD geng懂你的设备特性?
`ro.config.low_ram` 系统属性: 在低端设备上设为 true 时框架会使用geng激进的 minfree 参数;高端机型则保持宽松,以免频繁杀后台任务。
`sys.lmk.minfree_levels` 与 `sys.lmk.adj_levels` 动态属性: Ke以通过 adb shell setprop 动态修改,但需要重启 lmkd 才Neng生效;推荐配合自定义脚本根据剩余 RAM 自动调节。
`sys.sysctl.extra_free_kbytes`: 决定系统保留多少空闲页面用于 UI 渲染等关键场景,可通过 Framework 层计算屏幕像素大小后写入该属性,让渲染geng顺畅。
六、低内存杀手不是魔鬼,而是系统健康守护者 ⚡️The Low‑Memory‑Killer 在 Android 系统里扮演的是一种「提前防御」角色,它把原本只Neng等到 OOM 时才会出现的大灾难搬到了「可控」阶段。我们kan到,它不是孤立存在而是由 AMS 持续喂养 adj 数据,由 LmKd 将这些数据转译成 kernel Neng理解的阈值,再交给真正负责「拔刀斩」的大兄弟——kernel lowmemorykiller 完成任务。了解了这套链路,你Ke以geng有针对性地调优应用生命周期、合理设置后台服务权重,也Neng在调试卡顿问题时快速定位到底是哪一步卡住了。Ru果你觉得自己的手机总被「无情」地踢出后台,不妨先检查一下上述 sysfs 参数或自定义脚本,让它们geng贴合你的使用习惯吧!🚀
本文内容基于 Android 14 源码整理,并加入个人理解与实践经验。如需完整源码,请前往 AOSP 官方仓库查阅对应目录。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback