El proceso del daemon de optimización de poca memoria de Android (lmkd) supervisa el estado de la memoria de un sistema Android en ejecución y reacciona a la alta presión de la memoria finalizando los procesos menos esenciales para mantener el sistema funcionando a niveles aceptables.
Acerca de la presión de la memoria
Un sistema Android que ejecuta varios procesos en paralelo puede encontrarse en situaciones en las que se agota la memoria del sistema y los procesos que requieren más memoria experimentan retrasos notables. Presión de la memoria, un estado en el que el sistema se queda sin memoria, requiere que Android libere memoria (para aliviar la presión) mediante la limitación o la finalización de procesos no importantes, la solicitud de procesos para liberar recursos almacenados en caché no críticos, etcétera.
Históricamente, Android supervisaba la presión de la memoria del sistema con un controlador de optimización de poca memoria (LMK) en el kernel, un mecanismo rígido que depende de valores codificados. A partir del kernel 4.12, el controlador LMK se quitó del kernel superior y el lmkd del espacio del usuario realiza tareas de supervisión de la memoria y finalización de procesos.
Información de demora de presión
Android 10 y versiones posteriores admiten un nuevo modo lmkd que utiliza monitores de información de demora de presión (PSI) del kernel para la detección de presión de la memoria. El conjunto de parches PSI en el kernel superior (transferido a los kernels 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 superior también incluye monitores PSI que permiten que los procesos privilegiados del espacio del usuario (como lmkd) especifiquen umbrales para estos retrasos y se suscriban a eventos del kernel cuando se supera un umbral.
Monitores PSI en comparación con señales vmpressure
Debido a que las señales vmpressure (generadas por el kernel para la detección de presión de la memoria y utilizadas por lmkd) suelen incluir muchos falsos positivos, lmkd debe realizar un filtrado para determinar si la memoria está bajo presión real.
Esto genera activaciones lmkd innecesarias y el uso de recursos informáticos adicionales. El uso de monitores PSI genera una detección de presión de la memoria más precisa y minimiza la sobrecarga de filtrado.
Usa monitores PSI
Para usar monitores PSI en lugar de eventos vmpressure, configura la propiedad ro.lmk.use_psi. El valor predeterminado es true, lo que convierte a los monitores PSI en el mecanismo predeterminado de detección de presión de la memoria para lmkd. Debido a que los monitores PSI requieren compatibilidad con el kernel, este debe incluir los parches de transferencia PSI y compilarse con la compatibilidad con PSI habilitada (CONFIG_PSI=y).
Desventajas del controlador LMK en el kernel
Android da de baja el controlador LMK debido a varios problemas, incluidos los siguientes:
- Los dispositivos con poca RAM debían ajustarse de forma agresiva y, aun así, tenían un rendimiento deficiente en cargas de trabajo con una gran caché de páginas activa respaldada por archivos. El rendimiento deficiente provocó hiperpaginación y ninguna finalización.
- El controlador del kernel LMK se basaba en límites de memoria libre, sin escalamiento según 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 losas, que no se diseñó para operaciones pesadas, como buscar objetivos y finalizarlos, lo que ralentizó el proceso
vmscan.
LMKD de espacio del usuario
El lmkd del espacio del usuario implementa la misma funcionalidad que el controlador en el kernel, pero usa mecanismos existentes del kernel para detectar y estimar la presión de la memoria. Entre estos mecanismos, se incluyen el uso de eventos vmpressure generados por el kernel o monitores de información de demora de presión (PSI) para recibir 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 según la importancia del proceso.
Usa lmkd del espacio del usuario en Android 10
En Android 9 y versiones posteriores, el lmkd del espacio del usuario se activa si no se detecta un controlador LMK en el kernel. Debido a que el lmkd del espacio del usuario requiere compatibilidad con el kernel para los cgroups de memoria, el kernel debe compilarse con los siguientes parámetros de configuración:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Estrategias de finalización
El lmkd del espacio del usuario admite estrategias de finalización basadas en eventos vmpressure o monitores PSI, su gravedad y otras sugerencias, como el uso de intercambio. Las estrategias de finalización difieren entre los dispositivos de poca memoria y los de alto rendimiento:
- En los dispositivos de poca memoria, el sistema debe tolerar una mayor presión de la memoria como un modo de operación normal.
- En los dispositivos de alto rendimiento, la presión de la memoria debe considerarse una situación anormal y corregirse antes de que afecte el rendimiento general.
Puedes configurar la estrategia de finalización con la propiedad ro.config.low_ram.
El lmkd del espacio del usuario también admite un modo heredado en el que toma decisiones de finalización con las mismas estrategias que el controlador LMK en el kernel (es decir, umbrales de memoria libre y caché de archivos). Para habilitar el modo heredado, establece la propiedad ro.lmk.use_minfree_levels en true.
Configura lmkd
Configura lmkd para un dispositivo específico con las siguientes propiedades.
| Propiedad | Usar | Predeterminado |
|---|---|---|
ro.config.low_ram
|
Especifica si el dispositivo es de poca memoria o de alto rendimiento. | false
|
ro.lmk.use_psi |
Usa monitores PSI (en lugar de eventos vmpressure). |
true |
ro.lmk.use_minfree_levels
|
Usa umbrales de memoria libre y caché de archivos para tomar decisiones de finalización de procesos (es decir, haz coincidir la funcionalidad del controlador LMK en el kernel ). | false
|
ro.lmk.low
|
La puntuación oom_adj mínima para los procesos aptos para
finalizarse en un nivel vmpressure bajo.
|
1001(inhabilitado) |
ro.lmk.medium
|
La puntuación oom_adj mínima para los procesos aptos para
finalizarse en un nivel vmpressure medio.
|
800(servicios almacenados en caché o no esenciales) |
ro.lmk.critical
|
La puntuación mínima oom_adj para los procesos aptos para finalizarse en un nivel vmpressure crítico.
|
0(cualquier proceso) |
ro.lmk.critical_upgrade
|
Habilita la actualización al nivel crítico. | false
|
ro.lmk.upgrade_pressure
|
La mem_pressure máxima en la que se actualiza el nivel
porque el sistema está intercambiando demasiado.
|
100(inhabilitado) |
ro.lmk.downgrade_pressure
|
La mem_pressure mínima en la que se ignora un evento vmpressure
porque aún hay suficiente memoria libre disponible.
|
100(inhabilitado) |
ro.lmk.kill_heaviest_task
|
Finaliza la tarea apta más pesada (mejor decisión) en comparación con cualquier tarea apta (decisión rápida). | false
|
ro.lmk.kill_timeout_ms
|
Duración en milisegundos después de una finalización cuando no se realizará ninguna finalización adicional. | 0(inhabilitado) |
ro.lmk.debug
|
Habilita 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
Lmkd del espacio del usuario en Android 11
Android 11 mejora el lmkd con la introducción de una nueva estrategia de finalización. La estrategia de finalización usa un mecanismo PSI para la detección de presión de la memoria que se introdujo en Android 10. lmkd en Android 11 tiene en cuenta los niveles de uso de recursos de memoria y la hiperpaginación para evitar la falta de memoria y la degradación del rendimiento.
Esta estrategia de finalización reemplaza las estrategias anteriores y se puede usar en dispositivos de alto rendimiento y de poca RAM (Android Go).
Requisitos del kernel
Para los dispositivos Android 11, lmkd requiere las siguientes funciones del kernel:
- Incluye parches PSI y habilita PSI (transferencias disponibles en los kernels comunes de Android 4.9, 4.14 y 4.19).
- Incluye parches de compatibilidad con PIDFD (transferencias disponibles en los kernels comunes de Android 4.9, 4.14 y 4.19).
- Para dispositivos de poca RAM, incluye cgroups de memoria.
El kernel debe compilarse con los siguientes parámetros de configuración:
CONFIG_PSI=y
Configura lmkd en Android 11
La estrategia de finalización de memoria en Android 11 admite los botones de ajuste y los valores predeterminados que se indican a continuación. Estas funciones están disponibles en dispositivos de alto rendimiento y de poca RAM.
| Propiedad | Usar | Predeterminado | |
|---|---|---|---|
| Alto rendimiento | Poca RAM | ||
ro.lmk.psi_partial_stall_ms |
El umbral de demora PSI parcial, en milisegundos, para activar la notificación de poca memoria. Si el dispositivo recibe notificaciones de presión de la memoria demasiado tarde, disminuye este valor para activar notificaciones anteriores. Si las notificaciones de presión de la memoria se activan de forma innecesaria, aumenta este valor para que el dispositivo sea menos sensible al ruido. | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
El umbral de demora PSI completo, en milisegundos, para activar notificaciones de memoria críticas. Si el dispositivo recibe notificaciones de presión de la memoria críticas demasiado tarde, disminuye este valor para activar notificaciones anteriores. Si las notificaciones de presión de la memoria críticas se activan de forma innecesaria, aumenta este valor para que el dispositivo sea menos sensible al ruido. | 700 |
|
ro.lmk.thrashing_limit |
La cantidad máxima de errores de conjunto de trabajo como porcentaje del tamaño total de la caché de páginas respaldada por archivos. Los errores de conjunto de trabajo por encima de este valor significan que el sistema se considera que está paginando en exceso su caché de páginas. Si el rendimiento del dispositivo se ve afectado durante la presión de la memoria, disminuye el valor para limitar el exceso de paginación. Si el rendimiento del dispositivo se finaliza de forma innecesaria por motivos de hiperpaginación, aumenta el valor para permitir más hiperpaginación. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
La disminución del umbral de hiperpaginación expresada como un porcentaje del umbral original que se usa para disminuir el umbral cuando el sistema no se recupera, incluso después de una finalización. Si la hiperpaginación continua produce finalizaciones innecesarias, disminuye el valor. Si la respuesta al exceso de paginación continuo después de una finalización es demasiado lenta, aumenta el valor. | 10 |
50 |
ro.lmk.swap_util_max |
La cantidad máxima de memoria intercambiada como porcentaje de la memoria intercambiable total
memoria. Cuando la memoria intercambiada supera este límite, significa que el
sistema intercambió la mayor parte de su memoria intercambiable y aún está bajo presión.
Esto puede suceder cuando las asignaciones no intercambiables generan presión de la memoria
que no se puede aliviar mediante el intercambio porque la mayor parte de la memoria intercambiable
ya se intercambió. El valor predeterminado es 100, lo que inhabilita esta verificación de manera efectiva. Si el rendimiento del dispositivo se ve afectado durante
la presión de la memoria mientras el uso de intercambio es alto y el nivel de intercambio libre
no disminuye a ro.lmk.swap_free_low_percentage, disminuye
el valor para limitar el uso de intercambio. |
100 |
100 |
Los siguientes botones de ajuste antiguos también funcionan con la nueva estrategia de finalización.
| Propiedad | Usar | Predeterminado | |
|---|---|---|---|
| Alto rendimiento | Poca RAM | ||
ro.lmk.swap_free_low_percentage |
El nivel de intercambio libre como porcentaje del espacio de intercambio total. `lmkd` usa este valor como umbral para considerar que el sistema no tiene espacio de intercambio. Si `lmkd` finaliza mientras hay demasiado espacio en el intercambio, disminuye el porcentaje. Si las finalizaciones de `lmkd` ocurren demasiado tarde, lo que permite que se produzcan finalizaciones de OOM, aumenta el porcentaje. | 20 |
10 |
ro.lmk.debug |
Esto habilita los registros de depuración `lmkd`. Habilita la depuración durante el ajuste. | false |
|