Démon tueur de mémoire faible

Le processus Android Low Memory Killer Daemon ( lmkd ) surveille l'état de la mémoire d'un système Android en cours d'exécution et réagit à une pression élevée de la mémoire en supprimant les processus les moins essentiels pour maintenir les performances du système à des niveaux acceptables.

À propos de la pression de la mémoire

Un système Android exécutant plusieurs processus en parallèle peut rencontrer des situations dans lesquelles la mémoire système est épuisée et les processus nécessitant plus de mémoire subissent des retards notables. La pression de la mémoire , un état dans lequel le système manque de mémoire, nécessite qu'Android libère de la mémoire (pour alléger la pression) en limitant ou en supprimant les processus sans importance, en demandant aux processus de libérer les ressources mises en cache non critiques, etc.

Historiquement, Android surveillait la pression de la mémoire système à l’aide d’un pilote LMK (Low Memory Killer) intégré au noyau, un mécanisme rigide qui dépend de valeurs codées en dur. Depuis le noyau 4.12, le pilote LMK est supprimé du noyau en amont et l'espace utilisateur lmkd effectue des tâches de surveillance de la mémoire et de suppression de processus.

Informations sur le décrochage de pression

Android 10 et versions ultérieures prennent en charge un nouveau mode lmkd qui utilise les moniteurs d'informations de décrochage de pression du noyau (PSI) pour la détection de la pression de la mémoire. L'ensemble de correctifs PSI dans le noyau en amont (rétroporté vers les noyaux 4.9 et 4.14) mesure le temps pendant lequel les tâches sont retardées en raison d'un manque de mémoire. Comme ces retards affectent directement l’expérience utilisateur, ils représentent une mesure pratique pour déterminer la gravité de la pression sur la mémoire. Le noyau en amont comprend également des moniteurs PSI qui permettent aux processus de l'espace utilisateur privilégiés (tels que lmkd ) de spécifier des seuils pour ces délais et de s'abonner aux événements du noyau lorsqu'un seuil est dépassé.

Moniteurs PSI par rapport aux signaux vmpression

Étant donné que les signaux vmpressure (générés par le noyau pour la détection de la pression de la mémoire et utilisés par lmkd ) incluent souvent de nombreux faux positifs, lmkd doit effectuer un filtrage pour déterminer si la mémoire est sous pression réelle. Cela entraîne des réveils lmkd inutiles et l'utilisation de ressources de calcul supplémentaires. L'utilisation de moniteurs PSI permet une détection plus précise de la pression de la mémoire et minimise les frais de filtrage.

Utilisation des moniteurs PSI

Pour utiliser les moniteurs PSI au lieu des événements vmpressure , configurez la propriété ro.lmk.use_psi . La valeur par défaut est true , ce qui fait des moniteurs PSI le mécanisme par défaut de détection de la pression mémoire pour lmkd . Étant donné que les moniteurs PSI nécessitent la prise en charge du noyau, celui-ci doit inclure les correctifs de rétroportage PSI et être compilé avec la prise en charge PSI activée ( CONFIG_PSI=y ).

Inconvénients du pilote LMK intégré au noyau

Android déprécie le pilote LMK en raison d'un certain nombre de problèmes, notamment :

  • Les appareils à faible RAM devaient être réglés de manière agressive, et même dans ce cas, ils fonctionneraient mal sur les charges de travail avec un cache de page actif sauvegardé sur de gros fichiers. La mauvaise performance a entraîné des raclées et aucune victoire.
  • Le pilote du noyau LMK reposait sur des limites de mémoire libre, sans mise à l'échelle basée sur la pression de la mémoire.
  • En raison de la rigidité de la conception, les partenaires personnalisaient souvent le pilote afin qu'il fonctionne sur leurs appareils.
  • Le pilote LMK était connecté à l'API de réduction de dalle, qui n'était pas conçue pour des opérations lourdes telles que la recherche de cibles et leur destruction, ce qui ralentissait le processus vmscan .

Espace utilisateur lmkd

L'espace utilisateur lmkd implémente la même fonctionnalité que le pilote intégré au noyau mais utilise les mécanismes du noyau existants pour détecter et estimer la pression de la mémoire. De tels mécanismes incluent l'utilisation d'événements vmpressure générés par le noyau ou de moniteurs d'informations de décrochage de pression (PSI) pour obtenir des notifications sur les niveaux de pression de la mémoire, et l'utilisation des fonctionnalités de groupe de contrôle de mémoire pour limiter les ressources mémoire allouées à chaque processus en fonction de l'importance du processus.

Utilisation de l'espace utilisateur lmkd dans Android 10

Sous Android 9 et versions ultérieures, l'espace utilisateur lmkd s'active si un pilote LMK intégré au noyau n'est pas détecté. Étant donné que l'espace utilisateur lmkd nécessite la prise en charge par le noyau des groupes de contrôle de mémoire, le noyau doit être compilé avec les paramètres de configuration suivants :

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

Stratégies de mise à mort

Userspace lmkd prend en charge les stratégies d'élimination basées sur les événements vmpressure ou les moniteurs PSI, leur gravité et d'autres indices tels que l'utilisation du swap. Les stratégies d'élimination diffèrent entre les appareils à faible mémoire et les appareils hautes performances :

  • Sur les appareils disposant de peu de mémoire, le système doit tolérer une pression de mémoire plus élevée en mode de fonctionnement normal.
  • Sur les appareils hautes performances, la pression de la mémoire doit être considérée comme une situation anormale et corrigée avant qu'elle n'affecte les performances globales.

Vous pouvez configurer la stratégie kill à l'aide de la propriété ro.config.low_ram . Pour plus de détails, voir Configuration de RAM faible .

Userspace lmkd prend également en charge un mode hérité dans lequel il prend des décisions de mise à mort en utilisant les mêmes stratégies que le pilote LMK intégré au noyau (c'est-à-dire les seuils de mémoire libre et de cache de fichiers). Pour activer le mode hérité, définissez la propriété ro.lmk.use_minfree_levels sur true .

Configuration de lmkd

Configurez lmkd pour un périphérique spécifique à l'aide des propriétés suivantes.

Propriété Utiliser Défaut
ro.config.low_ram Spécifiez si le périphérique est un périphérique à faible RAM ou hautes performances. false
ro.lmk.use_psi Utilisez des moniteurs PSI (au lieu des événements vmpressure ). true
ro.lmk.use_minfree_levels Utilisez les seuils de mémoire libre et de cache de fichiers pour prendre des décisions d'arrêt de processus (c'est-à-dire faire correspondre les fonctionnalités du pilote LMK intégré au noyau). false
ro.lmk.low Le score oom_adj minimum pour les processus susceptibles d'être supprimés à un faible niveau vmpressure . 1001
(désactivé)
ro.lmk.medium Le score oom_adj minimum pour les processus susceptibles d'être supprimés à un niveau vmpressure moyenne. 800
(services mis en cache ou non essentiels)
ro.lmk.critical Le score oom_adj minimum pour les processus susceptibles d'être supprimés au niveau vmpressure critique. 0
(n'importe quel processus)
ro.lmk.critical_upgrade Activer la mise à niveau vers le niveau critique. false
ro.lmk.upgrade_pressure La mem_pressure maximale à laquelle le niveau est mis à niveau car le système échange trop. 100
(désactivé)
ro.lmk.downgrade_pressure mem_pressure minimale à laquelle un événement vmpressure est ignoré car suffisamment de mémoire libre est encore disponible. 100
(désactivé)
ro.lmk.kill_heaviest_task Supprimez la tâche éligible la plus lourde (meilleure décision) par rapport à n'importe quelle tâche éligible (décision rapide). true
ro.lmk.kill_timeout_ms Durée en millisecondes après un kill pendant laquelle aucun kill supplémentaire ne sera effectué. 0
(désactivé)
ro.lmk.debug Activez les journaux de débogage lmkd . false

Exemple de configuration d'appareil :

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

Espace utilisateur lmkd dans Android 11

Android 11 améliore le lmkd en introduisant une nouvelle stratégie de mise à mort. La stratégie de suppression utilise un mécanisme PSI pour la détection de la pression de la mémoire introduit dans Android 10. lmkd dans Android 11 prend en compte les niveaux d'utilisation des ressources mémoire et le thrashing pour éviter la famine de mémoire et la dégradation des performances. Cette stratégie de mise à mort remplace les stratégies précédentes et peut être utilisée à la fois sur des appareils hautes performances et à faible RAM (Android Go).

Exigences du noyau

Pour les appareils Android 11, lmkd nécessite les fonctionnalités de noyau suivantes :

  • Incluez les correctifs PSI et activez PSI (rétroportages disponibles dans les noyaux communs Android 4.9, 4.14 et 4.19).
  • Inclut les correctifs de prise en charge PIDFD (rétroportages disponibles dans les noyaux communs Android 4.9, 4.14 et 4.19).
  • Pour les appareils à faible RAM, incluez les groupes de contrôle de mémoire.

Le noyau doit être compilé avec les paramètres de configuration suivants :

CONFIG_PSI=y

Configuration de lmkd dans Android 11

La stratégie de suppression de mémoire dans Android 11 prend en charge les boutons de réglage et les valeurs par défaut répertoriés ci-dessous. Ces fonctionnalités fonctionnent à la fois sur les appareils hautes performances et à faible RAM.

Propriété Utiliser Défaut
Haute performance Faible RAM
ro.lmk.psi_partial_stall_ms Le seuil de décrochage partiel du PSI, en millisecondes, pour déclencher une notification de mémoire faible. Si l'appareil reçoit des notifications de pression de mémoire trop tard, diminuez cette valeur pour déclencher des notifications plus précoces. Si les notifications de pression de mémoire se déclenchent inutilement, augmentez cette valeur pour rendre l'appareil moins sensible au bruit. 70 200
ro.lmk.psi_complete_stall_ms Le seuil de décrochage PSI complet, en millisecondes, pour déclencher des notifications de mémoire critiques. Si l'appareil reçoit trop tard des notifications critiques de pression de mémoire, diminuez cette valeur pour déclencher des notifications plus précoces. Si des notifications critiques de pression de mémoire se déclenchent inutilement, augmentez cette valeur pour rendre l'appareil moins sensible au bruit. 700
ro.lmk.thrashing_limit Quantité maximale de défauts de l'ensemble de projets en pourcentage de la taille totale du cache de pages sauvegardé par fichier. Les défauts de l'ensemble de travail au-dessus de cette valeur signifient que le système est considéré comme étant en train de détruire son cache de pages. Si les performances de l'appareil sont affectées lors de la pression de la mémoire, diminuez la valeur pour limiter les ralentissements. Si les performances de l'appareil sont inutilement supprimées pour des raisons de turbulences, augmentez la valeur pour permettre davantage de turbulences. 100 30
ro.lmk.thrashing_limit_decay La diminution du seuil de thrashing, exprimée en pourcentage du seuil d'origine, est utilisée pour abaisser le seuil lorsque le système ne récupère pas, même après une mise à mort. Si une raclée continue produit des victimes inutiles, diminuez la valeur. Si la réponse aux coups continus après une mise à mort est trop lente, augmentez la valeur. 10 50
ro.lmk.swap_util_max Quantité maximale de mémoire échangée en pourcentage de la mémoire totale échangeable. Lorsque la mémoire échangée dépasse cette limite, cela signifie que le système a échangé la majeure partie de sa mémoire échangeable et qu'il est toujours sous pression. Cela peut se produire lorsque les allocations non échangeables génèrent une pression sur la mémoire qui ne peut pas être soulagée par l'échange, car la majeure partie de la mémoire échangeable est déjà échangée. La valeur par défaut est 100, ce qui désactive effectivement cette vérification. Si les performances de l'appareil sont affectées par la pression de la mémoire alors que l'utilisation du swap est élevée et que le niveau de swap gratuit ne descend pas à ro.lmk.swap_free_low_percentage , diminuez la valeur pour limiter l'utilisation du swap. 100 100

Les anciens boutons de réglage suivants fonctionnent également avec la nouvelle stratégie de mise à mort.

Propriété Utiliser Défaut
Haute performance Faible RAM
ro.lmk.swap_free_low_percentage Le niveau d'échange gratuit en pourcentage de l'espace d'échange total. `lmkd` utilise cette valeur comme seuil pour déterminer quand considérer le système comme manquant d'espace de swap. Si `lmkd` tue alors qu'il y a trop d'espace dans le swap, diminuez le pourcentage. Si les kills `lmkd` se produisent trop tard, permettant aux kills OOM de se produire, augmentez le pourcentage. 20 10
ro.lmk.debug Cela active les journaux de débogage `lmkd`. Activez le débogage pendant le réglage. false