Demonio asesino de poca memoria

El proceso Android Low Memory Killer Daemon ( 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 sistema funcionando 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. Presión de 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 eliminando procesos sin importancia, solicitando procesos para liberar recursos almacenados en caché no críticos, etc.

Históricamente, Android monitoreaba la presión de la memoria del sistema mediante un controlador LMK (low Memory Kill) interno del kernel, un mecanismo rígido que depende de valores codificados. 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 utiliza monitores de información de parada de presión del núcleo (PSI) para la detección de presión de la memoria. El conjunto de parches PSI en el kernel ascendente (portado a los kernels 4.9 y 4.14) mide la cantidad de tiempo que las tareas se retrasan 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 procesos de espacio de usuario privilegiados (como lmkd ) especifiquen umbrales para estos retrasos y se suscriban a eventos del kernel cuando se supera un umbral.

Monitores de PSI versus señales de presión vm

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 ) 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 reactivaciones 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.

Usando monitores PSI

Para utilizar monitores PSI en lugar de eventos vmpressure , configure la propiedad ro.lmk.use_psi . El valor predeterminado es true , lo que hace que PSI monitoree el mecanismo predeterminado de detección de presión de memoria para lmkd . Debido a que los monitores PSI requieren soporte del kernel, el kernel debe incluir los parches del backport de PSI y compilarse con el soporte de PSI habilitado ( CONFIG_PSI=y ).

Inconvenientes del controlador LMK interno

Android deja obsoleto el controlador LMK debido a una serie de problemas, que incluyen:

  • Los dispositivos con poca RAM tenían que ajustarse agresivamente, e incluso entonces funcionaban mal en cargas de trabajo con un gran caché de página activo respaldado por archivos. El mal desempeño resultó en palizas y ninguna muerte.
  • El controlador del kernel LMK se basaba en límites de memoria libre, sin escalamiento 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 del reductor de losa, que no estaba diseñada para operaciones pesadas como buscar objetivos y eliminarlos, lo que ralentizó el proceso vmscan .

Espacio de usuario lmkd

El espacio de usuario lmkd implementa la misma funcionalidad que el controlador interno del kernel, pero utiliza mecanismos existentes del kernel 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 parada de presión (PSI) para recibir notificaciones sobre los niveles de presión de la memoria, y el uso de funciones de grupo de memoria para limitar los recursos de memoria asignados a cada proceso según la importancia del proceso.

Usando el espacio de usuario lmkd en Android 10

En Android 9 y versiones posteriores, lmkd del espacio de usuario se activa si no se detecta un controlador LMK en el kernel. Debido a que el espacio de usuario lmkd requiere soporte del kernel para cgroups de memoria, el kernel debe compilarse con las siguientes configuraciones:

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

Estrategias de matar

Userspace lmkd admite estrategias de eliminación basadas en eventos vmpressure o monitores de PSI, su gravedad y otras sugerencias, como la utilización del intercambio. Las estrategias de eliminación difieren entre dispositivos con poca memoria y dispositivos de alto rendimiento:

  • En dispositivos con poca memoria, el sistema debería tolerar una mayor presión de memoria como modo de funcionamiento normal.
  • En dispositivos de alto rendimiento, la presión de la memoria debe verse como una situación anormal y solucionarse antes de que afecte el rendimiento general.

Puede configurar la estrategia de eliminación utilizando 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 eliminación utilizando las mismas estrategias que el controlador LMK interno (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 .

Configurando lmkd

Configure lmkd para un dispositivo específico usando las siguientes propiedades.

Propiedad Usar Por defecto
ro.config.low_ram Especifique si el dispositivo es un dispositivo de bajo RAM o de alto rendimiento. false
ro.lmk.use_psi Utilice monitores de PSI (en lugar de eventos vmpressure ). true
ro.lmk.use_minfree_levels Utilice umbrales de memoria caché de archivos y memoria libre para tomar decisiones de finalización de procesos (es decir, igualar la funcionalidad del controlador LMK interno). false
ro.lmk.low La puntuación mínima oom_adj para procesos elegibles para ser eliminados en un nivel bajo vmpressure . 1001
(desactivado)
ro.lmk.medium La puntuación mínima oom_adj para procesos elegibles para ser eliminados en un nivel medio vmpressure . 800
(servicios en caché o no esenciales)
ro.lmk.critical La puntuación mínima oom_adj para procesos elegibles para ser eliminados en un nivel crítico vmpressure . 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 está intercambiando demasiado. 100
(desactivado)
ro.lmk.downgrade_pressure La mem_pressure mínima a la que se ignora un evento vmpressure porque todavía hay suficiente memoria libre disponible. 100
(desactivado)
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 eliminación cuando no se realizará ninguna eliminación adicional. 0
(desactivado)
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 introducir una nueva estrategia para matar. 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 destrucción para evitar la falta de memoria y la degradación del rendimiento. Esta estrategia de eliminación reemplaza las estrategias anteriores y se puede utilizar tanto en dispositivos de alto rendimiento como de baja RAM (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 soporte PIDFD (backports disponibles en los núcleos comunes de Android 4.9, 4.14 y 4.19).
  • Para dispositivos con poca RAM, incluya grupos de memoria.

El kernel debe compilarse con los siguientes ajustes de configuración:

CONFIG_PSI=y

Configurando lmkd en Android 11

La estrategia de eliminación de memoria en Android 11 admite las perillas de ajuste y los valores predeterminados que se enumeran a continuación. Estas funciones funcionan tanto en dispositivos de alto rendimiento como de baja RAM.

Propiedad Usar Por defecto
Alto rendimiento RAM baja
ro.lmk.psi_partial_stall_ms El umbral de pérdida 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 más tempranas. Si las notificaciones de presión de la 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 pérdida 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 más tempranas. Si las notificaciones de presión crítica de la memoria 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 errores del conjunto de trabajo como porcentaje del tamaño total del caché de página respaldado por archivos. Los fallos del conjunto de trabajo por encima de este valor significan que se considera que el sistema está destruyendo 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 La caída del umbral de destrucción expresada como un porcentaje del umbral original utilizado para reducir el umbral cuando el sistema no se recupera, incluso después de una eliminación. 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 intercambiable como porcentaje de la memoria intercambiable total. Cuando la memoria intercambiada supera 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 presión en la memoria que no se puede aliviar mediante el intercambio porque la mayor parte de la memoria intercambiable ya está intercambiada. El valor predeterminado es 100, lo que efectivamente desactiva esta verificación. Si el rendimiento del dispositivo se ve afectado durante la presión de la memoria mientras la utilización del intercambio es alta y el nivel de intercambio libre no baja a ro.lmk.swap_free_low_percentage , reduzca el valor para limitar la utilización del intercambio. 100 100

Los siguientes botones de afinación antiguos también funcionan con la nueva estrategia de matar.

Propiedad Usar Por defecto
Alto rendimiento RAM baja
ro.lmk.swap_free_low_percentage El nivel de swap libre como porcentaje del espacio de swap total. `lmkd` usa este valor como umbral para determinar cuándo considerar que el sistema carece de espacio de intercambio. Si `lmkd` se interrumpe mientras hay demasiado espacio en el intercambio, disminuya el porcentaje. Si las eliminaciones de `lmkd` ocurren demasiado tarde, lo que permite que se produzcan 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