什么是 Low Memory Killer (LMK)?
Low Memory Killer 是 Android 内核(基于 Linux 内核)中的一个核心内存管理机制,当系统内存即将耗尽时,LMK 会被触发,它会根据一套预设的规则和优先级,强制杀死一些后台进程,以释放内存,确保前台正在运行的 Activity 和关键服务能够继续稳定运行,从而防止系统因内存不足而崩溃。

LMK Android 系统的“内存保镖”,在内存紧张时“牺牲”一些进程来保全大局。
LMK 的核心参数
LMK 的行为主要由一组内核参数控制,这些参数通常位于 /sys/module/lowmemorykiller/parameters/ 目录下,最重要的参数是 adj 和 minfree。
minfree 参数
- 作用:定义了内存的“警戒线”,它是一个由逗号分隔的数值列表,每个值对应一个内存阈值(单位通常是 KB)。
- 工作原理:当系统可用内存下降到
minfree列表中的某个阈值时,LMK 就会开始考虑杀死进程。 - 列表长度:
minfree列表的长度必须与adj列表的长度完全相同,通常在 Android 中,这个长度是 6,对应 6 个不同的进程优先级等级。
adj 参数
- 作用:定义了进程的“可杀性”等级,它也是一个由逗号分隔的整数值列表,每个值对应一个 OOM (Out-Of-Memory) score。
- 工作原理:
- 数值越小:表示进程的优先级越高,越不容易被杀死。
- 数值越大:表示进程的优先级越低,越容易被杀死。
- 与
minfree的对应关系:adj和minfree是一一对应的。minfree的第 N 个阈值和adj的第 N 个等级配对,当系统内存低于第 N 个阈值时,系统会优先杀死adj值大于或等于第 N 个等级的进程。
进程优先级等级 (adj 值)
Android 系统将进程分为几个明确的优先级等级,每个等级都有一个对应的 adj 值,理解这些等级是理解 LMK 的关键。
OOM Adjustment (adj) |
进程优先级等级 | 描述 | 示例 |
|---|---|---|---|
| -1000 | 不可杀 | 最优先级,绝对不能被杀死,通常是系统关键进程。 | zygote, surfaceflinger |
| -900 | 前台可见进程 | 通常是当前可见的 Activity (如对话框) 或系统 UI。 | 一个显示在屏幕上的 App |
| 800 | 不可见的前台进程 | 失去焦点但仍可见的进程 (如分屏模式下的另一个 App)。 | 处于分屏或画中画模式的 App |
| 700 | 主服务进程 | 正在运行的服务进程 (如音乐播放服务、下载服务)。 | 正在播放音乐的音乐 App |
| 600 | 可见的进程 | 包含一个可见的 Activity,但不在前台 (如被一个全屏对话框遮挡)。 | 被系统弹窗遮挡的 App |
| 500 | 次要服务进程 | 包含一个已启动的服务,但不属于前几类。 | 后台运行的服务 |
| 400 | 缓存进程 | 可被杀死的进程,当内存极度紧张时,首先被杀死,这些进程被保留在内存中以加快下次启动速度。 | 用户按了 Home 键后退到后台的 App |
| 300 | 空进程 | 不包含任何活动或服务的进程,纯粹为了缓存。 | 被彻底从任务列表中划掉的 App |
| 200 | Content Provider | 服务的进程。 | 某些 App 的 Content Provider |
| 100 | 持久进程 | 通常指系统核心服务,如电话、系统设置等。 | 电话 App、系统设置 |
| 0 | 前台进程 | 当前正在与用户交互的进程,这是最高优先级的用户进程。 | 用户正在使用的 App |
| 较大值 | 后台空进程 | 空闲的后台进程,随时可被回收。 | 完全在后台且无服务的 App |
注意:不同 Android 版本和厂商定制 ROM 中,这些 adj 值可能会有细微差异,但核心逻辑和等级划分基本一致。

minfree 和 adj 的对应关系 (示例)
假设我们有一组典型的参数配置:
# cat /sys/module/lowmemorykiller/parameters/minfree 18432,23040,27648,34816,46080,86016 # cat /sys/module/lowmemorykiller/parameters/adj 0,200,400,900,1000,1200
这组参数可以这样解读:
-
当可用内存 <= 86MB (86016 KB):
- 系统会开始杀死
adj值 >= 1200 的进程,这些通常是空进程,可以被安全地杀死而不会影响用户体验。
- 系统会开始杀死
-
当可用内存 <= 45MB (46080 KB):
(图片来源网络,侵删)- 系统会开始杀死
adj值 >= 1000 的进程,这包括adj=1200的进程,如果还存在的话。
- 系统会开始杀死
-
当可用内存 <= 34MB (34816 KB):
- 系统会开始杀死
adj值 >= 900 的进程,这通常包括缓存进程 (如用户按了 Home 键的 App)。
- 系统会开始杀死
-
当可用内存 <= 27MB (27648 KB):
- 系统会开始杀死
adj值 >= 400 的进程,这可能会影响到一些次要服务进程。
- 系统会开始杀死
-
当可用内存 <= 22.5MB (23040 KB):
- 系统会开始杀死
adj值 >= 200 的进程,这可能会影响到可见的进程或Content Provider,系统会非常谨慎地处理。
- 系统会开始杀死
-
当可用内存 <= 18MB (18432 KB):
- 系统会开始杀死
adj值 >= 0 的进程,这包括前台进程!这是最严重的情况,系统为了不崩溃,可能会杀死用户正在使用的 App,导致 App 被强制关闭。
- 系统会开始杀死
如何查看和修改这些参数?
查看当前参数
# 使用 cat 命令查看 cat /sys/module/lowmemorykiller/parameters/minfree cat /sys/module/lowmemorykiller/parameters/adj # 使用 dumpsys 命令查看更详细的内存信息 dumpsys meminfo
重要提示:在大多数设备上,这些文件是只读的,普通应用甚至 Root 后的普通用户也无法直接修改,修改这些参数通常需要重新编译内核或使用特定的系统级工具(如一些厂商的开发者选项或 Magisk 模块)。
修改参数的风险
- 修改
minfree值过高:将所有minfree值都设置得很大,这会导致系统在内存很低时才触发 LMK,后台会堆积大量进程,最终可能导致应用切换卡顿,甚至系统整体响应缓慢。 - 修改
adj值不合理:降低某个重要进程类型的adj值,可能会让它在不该被杀死的时候被杀死,导致系统功能异常。
对于普通用户和开发者来说,了解 LMK 的工作原理比去修改它更重要,系统厂商已经根据设备硬件和 ROM 特性对 LMK 参数进行了调优。
LMK 的演进:LMKd
在较新的 Android 版本中(尤其是 Android 9+),LMK 的用户态部分被一个名为 lmkd (Low Memory Daemon) 的守护进程所取代。
- LMK (内核态):仍然保留在内核中,负责最终执行杀死进程的操作。
- lmkd (用户态):负责监听内存压力信号,并根据更复杂的策略(如进程的内存占用、CPU 使用情况等)来决定哪些进程应该被杀死,然后通过
ioctl系统调用通知内核 LMK。
这种设计将决策逻辑从内核移到了用户空间,使得策略更新和调试更加灵活和安全,并且减少了内核态的复杂性。
| 参数 | 作用 | 示例值 | 核心逻辑 |
|---|---|---|---|
minfree |
内存阈值列表 | 18432,23040,... |
当可用内存 <= � |
