The Android low memory killer daemon (
lmkd) process monitors the memory
state of a running Android system and reacts to high memory pressure by killing
the least essential processes to keep the system performing at acceptable
About memory pressure
An Android system running multiple processes in parallel may encounter situations when system memory is exhausted and processes that require more memory experience noticeable delays. Memory pressure, a state in which the system is running short on memory, requires Android to free memory (to alleviate the pressure) by throttling or killing unimportant processes, requesting processes to free noncritical cached resources, and so on.
Historically, Android monitored system memory pressure using an in-kernel
low memory killer (LMK) driver, a rigid mechanism that depends on hard-coded
values. As of kernel 4.12, the LMK driver is removed from the upstream
kernel and the userspace
lmkd performs memory monitoring and process killing
Pressure stall information
Android 10 and later support a new
lmkd mode that
uses kernel pressure stall information (PSI) monitors for memory pressure
detection. The PSI patchset in the upstream kernel (backported to 4.9 and 4.14
kernels) measures the amount of time that tasks are delayed as a result of
memory shortages. As these delays directly affect user experience, they
represent a convenient metric for determining memory pressure severity. The
upstream kernel also includes PSI monitors that allow privileged userspace
processes (such as
lmkd) to specify thresholds for these delays and to
subscribe to events from the kernel when a threshold is breached.
PSI monitors versus vmpressure signals
vmpressure signals (generated by the kernel for memory
pressure detection and used by
lmkd) often include numerous false positives,
lmkd must perform filtering to determine if the memory is under real pressure.
This results in unnecessary
lmkd wakeups and the use of additional
computational resources. Using PSI monitors results in more accurate memory
pressure detection and minimizes filtering overhead.
Using PSI monitors
To use PSI monitors instead of
vmpressure events, configure the
ro.lmk.use_psi property. The default is
true, making PSI monitors the
default mechanism of memory pressure detection for
lmkd. Because PSI monitors
require kernel support, the kernel must include the PSI backport patches and be
compiled with PSI support enabled (
Drawbacks of in-kernel LMK driver
Android deprecates the LMK driver due to a number of issues, including:
- Low-RAM devices had to be tuned aggressively, and even then would perform poorly on workloads with large file-backed active pagecache. The poor performance resulted in thrashing and no kills.
- The LMK kernel driver relied on free-memory limits, with no scaling based on the memory pressure.
- Because of the rigidity of the design, partners often customized the driver so that it would work on their devices.
- The LMK driver hooked into the slab shrinker API, which wasn't
designed for heavy operations such as searching for targets and killing
them, which slowed down the
lmkd implements the same functionality as the in-kernel driver
but uses existing kernel mechanisms to detect and estimate memory pressure. Such
mechanisms include using kernel-generated
vmpressure events or pressure stall
information (PSI) monitors to get notifications about memory pressure levels,
and using memory cgroup features to limit the memory resources allocated to each
process based on process importance.
Using userspace lmkd in Android 10
In Android 9 and later, userspace
lmkd activates if
an in-kernel LMK driver isn't detected. Because userspace
requires kernel support for memory cgroups, the kernel must be compiled with the
following configuration settings:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y
lmkd supports kill strategies based on
vmpressure events or PSI
monitors, their severity, and other hints such as swap utilization. Kill
strategies differ between low-memory and high-performance devices:
- On low-memory devices, the system should tolerate higher memory pressure as a normal mode of operation.
- On high-performance devices, memory pressure should be viewed as an abnormal situation and fixed before it affects overall performance.
You can configure the kill strategy using the
(for details, see Low RAM Configuration).
lmkd also supports a legacy mode in which it makes kill decisions
using the same strategies as the in-kernel LMK driver (that is, free
memory and file cache thresholds). To enable legacy mode, set the
ro.lmk.use_minfree_levels property to
lmkd for a specific device using the following properties.
||Specify if the device is a low-RAM or high-performance device.||
||Use PSI monitors (instead of
||Use free memory and file cache thresholds for making process kill decisions (that is, match the functionality of the in-kernel LMK driver).||
(cached or nonessential services)
||Enable upgrade to critical level.||
||Kill the heaviest eligible task (best decision) versus any eligible task (fast decision).||
||Duration in milliseconds after a kill when no additional kill will be done.||
Example device configuration:
PRODUCT_PROPERTY_OVERRIDES += \ ro.lmk.low=1001 \ ro.lmk.medium=800 \ ro.lmk.critical=0 \ ro.lmk.critical_upgrade=false \ ro.lmk.upgrade_pressure=100 \ ro.lmk.downgrade_pressure=100 \ ro.lmk.kill_heaviest_task=true
Userspace lmkd in Android 11
Android 11 improves the
lmkd by introducing a new
killing strategy. The killing strategy uses a PSI mechanism for memory pressure
detection introduced in Android 10.
Android 11 accounts for memory resource use levels
and thrashing to prevent memory starvation and performance degradation.
This killing strategy replaces previous strategies and can be used on both
high-performance and low-RAM (Android Go) devices.
For Android 11 devices,
lmkd requires the following
- Include PSI patches and enable PSI (backports available in Android common kernels 4.9, 4.14, and 4.19).
- Include PIDFD support patches (backports available in Android common kernels 4.9, 4.14, and 4.19).
- For low-RAM devices, include memory cgroups.
The kernel must be compiled with the following configuration settings:
Configuring lmkd in Android 11
The memory killing strategy in Android 11 supports the tuning knobs and defaults listed below. These features work on both high-performance and low-RAM devices.
|High performance||Low RAM|
||The partial PSI stall threshold, in milliseconds, for triggering low memory notification. If the device receives memory pressure notifications too late, decrease this value to trigger earlier notifications. If memory pressure notifications trigger unnecessarily, increase this value to make the device less sensitive to noise.||
||The complete PSI stall threshold, in milliseconds, for triggering critical memory notifications. If the device receives critical memory pressure notifications too late, decrease this value to trigger earlier notifications. If critical memory pressure notifications trigger unnecessarily, increase this value to make the device less sensitive to noise.||
||The max amount of workingset refaults as a percentage of the total file-backed pagecache size. Workingset refaults above this value mean that the system is considered to be thrashing its pagecache. If the performance of the device is affected during memory pressure, decrease the value to limit thrashing. If the performance of the device is killed unnecessarily for thrashing reasons, increase the value to allow more thrashing.||
||The thrashing threshold decay expressed as a percentage of the original threshold used to lower the threshold when the system doesn’t recover, even after a kill. If continuous thrashing produces unnecessary kills, decrease the value. If the response to continuous thrashing after a kill is too slow, increase the value.||
||The max amount of swapped memory as a percentage of the total swappable
memory. When swapped memory grows over this limit, it means that the
system swapped most of its swappable memory and is still under pressure.
This can happen when non-swappable allocations are generating memory
pressure which can't be relieved by swapping because most of the swappable
memory is already swapped out. The default value is 100, which effectively
disables this check. If the performance of the device is affected during
memory pressure while swap utilization is high and the free swap level
isn't dropping to
The following old tuning knobs also work with the new killing strategy.
|High performance||Low RAM|
||The level of free swap as a percentage of the total swap space. `lmkd` uses this value as a threshold for when to consider the system as swap space starved. If `lmkd` kills while there's too much space in swap, decrease the percentage. If `lmkd` kills happen too late, allowing OOM kills to happen, increase the percentage.||
||This enables `lmkd` debug logs. Enable debug while tuning.||