El proceso del demonio asesino de memoria baja de Android ( lmkd
) monitorea el estado de la memoria de un sistema Android en ejecución y reacciona a la alta presión de la memoria eliminando los procesos menos esenciales para mantener el rendimiento del sistema a niveles aceptables.
Sobre la presión de la memoria
Un sistema Android que ejecuta varios procesos en paralelo puede encontrar situaciones en las que la memoria del sistema se agota y los procesos que requieren más memoria experimentan retrasos notables. La presión de la memoria , un estado en el que el sistema se está quedando sin memoria, requiere que Android libere memoria (para aliviar la presión) acelerando o matando procesos sin importancia, solicitando procesos para liberar recursos en caché no críticos, etc.
Históricamente, Android monitoreaba la presión de la memoria del sistema mediante un controlador LMK (low memory killer) en el núcleo, un mecanismo rígido que depende de valores codificados de forma rígida. A partir del kernel 4.12, el controlador LMK se elimina del kernel ascendente y el espacio de usuario lmkd
realiza tareas de monitoreo de memoria y eliminación de procesos.
Información de pérdida de presión
Android 10 y versiones posteriores admiten un nuevo modo lmkd
que usa monitores de información de bloqueo de presión (PSI) del núcleo para la detección de presión de memoria. El conjunto de parches de PSI en el núcleo ascendente (retrocedido a los núcleos 4.9 y 4.14) mide la cantidad de tiempo que se retrasan las tareas como resultado de la escasez de memoria. Como estos retrasos afectan directamente la experiencia del usuario, representan una métrica conveniente para determinar la gravedad de la presión de la memoria. El kernel ascendente también incluye monitores PSI que permiten que los procesos de espacio de usuario privilegiado (como lmkd
) especifiquen umbrales para estos retrasos y se suscriban a eventos del kernel cuando se infringe un umbral.
Monitores PSI frente a señales de vmpresión
Debido a que las señales de vmpressure
(generadas por el kernel para la detección de la presión de la memoria y utilizadas por lmkd
) a menudo incluyen numerosos falsos positivos, lmkd
debe realizar un filtrado para determinar si la memoria está bajo presión real. Esto da como resultado activaciones innecesarias lmkd
y el uso de recursos computacionales adicionales. El uso de monitores PSI da como resultado una detección de presión de memoria más precisa y minimiza la sobrecarga de filtrado.
Uso de monitores PSI
Para usar monitores PSI en lugar de eventos vmpressure
, configure la propiedad ro.lmk.use_psi
. El valor predeterminado es true
, lo que hace que los monitores PSI sean el mecanismo predeterminado de detección de presión de memoria para lmkd
. Debido a que los monitores de PSI requieren compatibilidad con el kernel, el kernel debe incluir los parches de backport de PSI y compilarse con la compatibilidad con PSI habilitada ( CONFIG_PSI=y
).
Inconvenientes del controlador LMK en el kernel
Android desaprueba el controlador LMK debido a una serie de problemas, que incluyen:
- Los dispositivos con poca RAM tenían que ajustarse agresivamente, e incluso entonces tendrían un rendimiento deficiente en cargas de trabajo con un gran caché de página activo respaldado por archivos. El mal desempeño resultó en palizas y sin muertes.
- El controlador del kernel LMK se basó en los límites de memoria libre, sin escalado basado en la presión de la memoria.
- Debido a la rigidez del diseño, los socios solían personalizar el controlador para que funcionara en sus dispositivos.
- El controlador LMK se conectó a la API de reducción de losa, que no fue diseñada para operaciones pesadas como buscar objetivos y matarlos, lo que ralentizó el proceso de
vmscan
.
espacio de usuario lmkd
El espacio de usuario lmkd
implementa la misma funcionalidad que el controlador del núcleo, pero utiliza los mecanismos del núcleo existentes para detectar y estimar la presión de la memoria. Dichos mecanismos incluyen el uso de eventos vmpressure
generados por el kernel o monitores de información de bloqueo de presión (PSI) para obtener notificaciones sobre los niveles de presión de la memoria y el uso de funciones de cgroup de memoria para limitar los recursos de memoria asignados a cada proceso en función de la importancia del proceso.
Usando el espacio de usuario lmkd en Android 10
En Android 9 y versiones posteriores, el espacio de usuario lmkd
activa si no se detecta un controlador LMK en el kernel. Debido a que el espacio de usuario lmkd
requiere soporte de kernel para cgroups de memoria, el kernel debe compilarse con los siguientes ajustes de configuración:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Matar estrategias
Userspace lmkd
admite estrategias de eliminación basadas en eventos de vmpressure
o monitores PSI, su gravedad y otras sugerencias, como la utilización de intercambio. Las estrategias de eliminación difieren entre los dispositivos de memoria baja y los de alto rendimiento:
- En dispositivos con poca memoria, el sistema debe tolerar una mayor presión de memoria como modo de funcionamiento normal.
- En los dispositivos de alto rendimiento, la presión de la memoria debe verse como una situación anormal y corregirse antes de que afecte el rendimiento general.
Puede configurar la estrategia de eliminación mediante la propiedad ro.config.low_ram
. Para obtener más información, consulte Configuración de RAM baja .
Userspace lmkd
también admite un modo heredado en el que toma decisiones de finalización utilizando las mismas estrategias que el controlador LMK en el kernel (es decir, memoria libre y umbrales de caché de archivos). Para habilitar el modo heredado, establezca la propiedad ro.lmk.use_minfree_levels
en true
.
Configuración de lmkd
Configure lmkd
para un dispositivo específico usando las siguientes propiedades.
Propiedad | Usar | Defecto |
---|---|---|
ro.config.low_ram | Especifique si el dispositivo es un dispositivo con poca memoria RAM o de alto rendimiento. | false |
ro.lmk.use_psi | Use monitores PSI (en lugar de eventos de vmpressure ). | true |
ro.lmk.use_minfree_levels | Utilice la memoria libre y los umbrales de caché de archivos para tomar decisiones de terminación de procesos (es decir, igualar la funcionalidad del controlador LMK en el kernel). | false |
ro.lmk.low | La puntuación mínima de oom_adj para los procesos aptos para eliminarse a un nivel de presión de vmpressure bajo. | 1001 (discapacitado) |
ro.lmk.medium | La puntuación mínima de oom_adj para los procesos aptos para eliminarse en un nivel de vmpressure medio. | 800 (servicios almacenados en caché o no esenciales) |
ro.lmk.critical | La puntuación mínima de oom_adj para los procesos aptos para eliminarse en un nivel de presión de vmpressure crítico. | 0 (cualquier proceso) |
ro.lmk.critical_upgrade | Habilite la actualización al nivel crítico. | false |
ro.lmk.upgrade_pressure | La mem_pressure máxima a la que se actualiza el nivel porque el sistema se está intercambiando demasiado. | 100 (discapacitado) |
ro.lmk.downgrade_pressure | La mem_pressure mínima en la que se ignora un evento de vmpressure porque todavía hay suficiente memoria libre disponible. | 100 (discapacitado) |
ro.lmk.kill_heaviest_task | Elimine la tarea elegible más pesada (mejor decisión) frente a cualquier tarea elegible (decisión rápida). | true |
ro.lmk.kill_timeout_ms | Duración en milisegundos después de una muerte cuando no se realizará ninguna muerte adicional. | 0 (discapacitado) |
ro.lmk.debug | Habilite los registros de depuración lmkd . | false |
Ejemplo de configuración del dispositivo:
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
Espacio de usuario lmkd en Android 11
Android 11 mejora el lmkd
al presentar una nueva estrategia de asesinato. La estrategia de eliminación utiliza un mecanismo PSI para la detección de presión de memoria introducido en Android 10. lmkd
en Android 11 tiene en cuenta los niveles de uso de recursos de memoria y la paliza para evitar el agotamiento de la memoria y la degradación del rendimiento. Esta estrategia de destrucción reemplaza a las estrategias anteriores y se puede usar tanto en dispositivos de alto rendimiento como de RAM baja (Android Go).
Requisitos del núcleo
Para dispositivos con Android 11, lmkd
requiere las siguientes características del kernel:
- Incluya parches de PSI y habilite PSI (backports disponibles en los núcleos comunes de Android 4.9, 4.14 y 4.19).
- Incluya parches de compatibilidad con PIDFD (backports disponibles en los kernels comunes de Android 4.9, 4.14 y 4.19).
- Para dispositivos con poca RAM, incluya cgroups de memoria.
El kernel debe compilarse con los siguientes ajustes de configuración:
CONFIG_PSI=y
Configuración de lmkd en Android 11
La estrategia de destrucción de memoria en Android 11 es compatible con las perillas de ajuste y los valores predeterminados que se enumeran a continuación. Estas funciones funcionan tanto en dispositivos de alto rendimiento como en dispositivos con poca memoria RAM.
Propiedad | Usar | Defecto | |
---|---|---|---|
Alto rendimiento | RAM baja | ||
ro.lmk.psi_partial_stall_ms | El umbral de bloqueo de PSI parcial, en milisegundos, para activar la notificación de memoria baja. Si el dispositivo recibe notificaciones de presión de memoria demasiado tarde, disminuya este valor para activar notificaciones anteriores. Si las notificaciones de presión de memoria se activan innecesariamente, aumente este valor para que el dispositivo sea menos sensible al ruido. | 70 | 200 |
ro.lmk.psi_complete_stall_ms | El umbral completo de bloqueo de PSI, en milisegundos, para activar notificaciones de memoria crítica. Si el dispositivo recibe notificaciones de presión de memoria crítica demasiado tarde, disminuya este valor para activar notificaciones anteriores. Si las notificaciones de presión de memoria crítica se activan innecesariamente, aumente este valor para que el dispositivo sea menos sensible al ruido. | 700 | |
ro.lmk.thrashing_limit | La cantidad máxima de valores predeterminados del conjunto de trabajo como porcentaje del tamaño total de la memoria caché de la página respaldada por el archivo. Los valores predeterminados del conjunto de trabajo por encima de este valor significan que se considera que el sistema está golpeando su caché de página. Si el rendimiento del dispositivo se ve afectado durante la presión de la memoria, disminuya el valor para limitar la paliza. Si el rendimiento del dispositivo se interrumpe innecesariamente por motivos de paliza, aumente el valor para permitir más paliza. | 100 | 30 |
ro.lmk.thrashing_limit_decay | El decaimiento del umbral de paliza expresado como un porcentaje del umbral original utilizado para reducir el umbral cuando el sistema no se recupera, incluso después de una muerte. Si la paliza continua produce muertes innecesarias, disminuya el valor. Si la respuesta a la paliza continua después de una muerte es demasiado lenta, aumente el valor. | 10 | 50 |
ro.lmk.swap_util_max | La cantidad máxima de memoria intercambiada como porcentaje de la memoria intercambiable total. Cuando la memoria intercambiada crece por encima de este límite, significa que el sistema intercambió la mayor parte de su memoria intercambiable y todavía está bajo presión. Esto puede suceder cuando las asignaciones no intercambiables generan una presión de memoria que no se puede aliviar mediante el intercambio porque la mayor parte de la memoria intercambiable ya se ha intercambiado. El valor predeterminado es 100, lo que deshabilita efectivamente esta verificación. Si el rendimiento del dispositivo se ve afectado durante la presión de la memoria mientras la utilización de intercambio es alta y el nivel de intercambio libre no cae a ro.lmk.swap_free_low_percentage , reduzca el valor para limitar la utilización de intercambio. | 100 | 100 |
Las siguientes perillas de afinación antiguas también funcionan con la nueva estrategia de matar.
Propiedad | Usar | Defecto | |
---|---|---|---|
Alto rendimiento | RAM baja | ||
ro.lmk.swap_free_low_percentage | El nivel de intercambio libre como porcentaje del espacio de intercambio total. `lmkd` usa este valor como un umbral para considerar el sistema como falto de espacio de intercambio. Si `lmkd` mata mientras hay demasiado espacio en el intercambio, disminuya el porcentaje. Si las eliminaciones de `lmkd` ocurren demasiado tarde, lo que permite que ocurran eliminaciones de OOM, aumente el porcentaje. | 20 | 10 |
ro.lmk.debug | Esto habilita los registros de depuración `lmkd`. Habilite la depuración durante el ajuste. | false |