Le processus du daemon du tueur de mémoire faible Android (lmkd
) surveille l'état de la mémoire d'un système Android en cours d'exécution et réagit à une pression de mémoire élevée en fermant 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 où la mémoire système est épuisée et que les processus qui nécessitent plus de mémoire subissent des retards notables. La pression de mémoire, un état dans lequel le système manque de mémoire, oblige Android à libérer de la mémoire (pour atténuer la pression) en limitant ou en fermant les processus sans importance, en demandant aux processus de libérer des 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) dans le noyau, un mécanisme rigide qui dépend de valeurs codées en dur. À partir du kernel 4.12, le pilote LMK est supprimé du kernel en amont, et l'espace utilisateur lmkd
effectue la surveillance de la mémoire et les tâches d'arrêt des processus.
Informations sur les blocages de pression
Android 10 et les versions ultérieures sont compatibles avec un nouveau mode lmkd
qui utilise les informations sur les blocages de pression du noyau (PSI) pour détecter la pression sur la mémoire. Le correctif PSI du kernel en amont (porté en arrière vers les kernels 4.9 et 4.14) mesure la durée pendant laquelle les tâches sont retardées en raison de pénuries de mémoire. Comme ces retards affectent directement l'expérience utilisateur, ils représentent une métrique pratique pour déterminer la gravité de la pression sur la mémoire. Le kernel en amont inclut également des moniteurs PSI qui permettent aux processus d'espace utilisateur privilégiés (tels que lmkd
) de spécifier des seuils pour ces retards et de s'abonner aux événements du kernel lorsqu'un seuil est dépassé.
Surveillance PSI et signaux vmpressure
É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 soumise à une 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 de détecter plus précisément la pression de la mémoire et de réduire les coûts de filtrage.
Utiliser des moniteurs PSI
Pour utiliser des moniteurs PSI au lieu d'événements vmpressure
, configurez la propriété ro.lmk.use_psi
. La valeur par défaut est true
, ce qui signifie que PSI surveille le mécanisme par défaut de détection de la pression sur la mémoire pour lmkd
. Étant donné que les moniteurs PSI nécessitent la prise en charge du noyau, le noyau doit inclure les correctifs de rétroportage PSI et être compilé avec la prise en charge de PSI activée (CONFIG_PSI=y
).
Inconvénients du pilote LMK dans le noyau
Android abandonne le pilote LMK en raison de plusieurs problèmes, dont les suivants:
- Les appareils à faible mémoire vive devaient être configurés de manière agressive, et même dans ce cas, leurs performances étaient médiocres pour les charges de travail avec un grand cache de pages actif basé sur des fichiers. Les mauvaises performances ont entraîné des accès aléatoires et aucun "kill".
- Le pilote du noyau LMK s'appuyait sur des limites de mémoire libre, sans mise à l'échelle en fonction de la pression sur la mémoire.
- En raison de la rigidité de la conception, les partenaires ont souvent personnalisé le pilote pour qu'il fonctionne sur leurs appareils.
- Le pilote LMK était connecté à l'API de réduction des dalles, qui n'était pas conçue pour les opérations lourdes telles que la recherche de cibles et leur suppression, ce qui ralentissait le processus
vmscan
.
lmkd de l'espace utilisateur
L'lmkd
de l'espace utilisateur implémente la même fonctionnalité que le pilote du noyau, mais utilise les mécanismes de noyau existants pour détecter et estimer la pression de la mémoire. Ces mécanismes incluent l'utilisation d'événements vmpressure
générés par le noyau ou de moniteurs d'informations sur les arrêts dus à la pression (PSI) pour recevoir des notifications sur les niveaux de pression de la mémoire, et l'utilisation des fonctionnalités de cgroup de mémoire pour limiter les ressources de mémoire attribuées à chaque processus en fonction de son importance.
Utiliser l'espace utilisateur lmkd dans Android 10
Sous Android 9 et versions ultérieures, l'espace utilisateur lmkd
s'active si un pilote LMK dans le noyau n'est pas détecté. Étant donné que l'espace utilisateur lmkd
nécessite la prise en charge du noyau pour les groupes 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 d'arrêt
lmkd
dans l'espace utilisateur prend en charge les stratégies d'arrêt basées sur des événements vmpressure
ou des moniteurs PSI, leur gravité et d'autres indices tels que l'utilisation de l'espace de swap. Les stratégies d'arrêt diffèrent entre les appareils à faible mémoire et les appareils hautes performances:
- Sur les appareils à faible mémoire, le système doit tolérer une pression de mémoire plus élevée en tant que mode de fonctionnement normal.
- Sur les appareils hautes performances, la pression sur 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 d'arrêt à l'aide de la propriété ro.config.low_ram
. Pour en savoir plus, consultez la section Configuration de la RAM faible.
L'espace utilisateur lmkd
est également compatible avec un ancien mode dans lequel il prend des décisions d'arrêt en utilisant les mêmes stratégies que le pilote LMK du noyau (c'est-à-dire les seuils de mémoire libre et de cache de fichiers). Pour activer l'ancien mode, définissez la propriété ro.lmk.use_minfree_levels
sur true
.
Configurer lmkd
Configurez lmkd
pour un appareil spécifique à l'aide des propriétés suivantes.
Propriété | Utiliser | Par défaut |
---|---|---|
ro.config.low_ram
|
Spécifiez s'il s'agit d'un appareil à mémoire RAM faible ou hautes performances. | false
|
ro.lmk.use_psi |
Utilisez des moniteurs PSI (au lieu d'événements vmpressure ). |
true |
ro.lmk.use_minfree_levels
|
Utilisez des seuils de mémoire libre et de cache de fichiers pour prendre des décisions d'arrêt de processus (c'est-à-dire correspondre à la fonctionnalité du pilote LMK dans le noyau). | false
|
ro.lmk.low
|
Score oom_adj minimal pour les processus pouvant être arrêtés à un niveau vmpressure faible.
|
1001 (désactivé) |
ro.lmk.medium
|
Score oom_adj minimal pour les processus pouvant être arrêtés au niveau vmpressure moyen.
|
800 (services mis en cache ou non essentiels) |
ro.lmk.critical
|
Score oom_adj minimal pour les processus pouvant être arrêtés au niveau vmpressure critique.
|
0 (tout processus) |
ro.lmk.critical_upgrade
|
Activez la mise à niveau au niveau critique. | false
|
ro.lmk.upgrade_pressure
|
mem_pressure maximal à partir duquel le niveau est mis à niveau, car le système échange trop.
|
100 (désactivé) |
ro.lmk.downgrade_pressure
|
mem_pressure minimal à partir duquel un événement vmpressure est ignoré, car suffisamment de mémoire libre est toujours disponible.
|
100 (désactivé) |
ro.lmk.kill_heaviest_task
|
Arrêter la tâche éligible la plus lourde (meilleure décision) par rapport à toute tâche éligible (décision rapide). | false
|
ro.lmk.kill_timeout_ms
|
Durée en millisecondes entre l'arrêt et l'absence d'arrêt supplémentaire. | 0 (désactivé) |
ro.lmk.debug
|
Activez les journaux de débogage lmkd .
|
false
|
Exemple de configuration de l'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
Lmkd de l'espace utilisateur dans Android 11
Android 11 améliore lmkd
en introduisant une nouvelle stratégie d'arrêt. La stratégie d'arrêt utilise un mécanisme PSI pour la détection de la pression de mémoire introduit dans Android 10. lmkd
dans Android 11 tient compte des niveaux d'utilisation des ressources de mémoire et des accès aléatoires pour éviter l'épuisement de la mémoire et la dégradation des performances.
Cette stratégie de fermeture remplace les stratégies précédentes et peut être utilisée à la fois sur les appareils hautes performances et sur les appareils à 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 (versions antérieures disponibles dans les noyaux communs Android 4.9, 4.14 et 4.19).
- Inclut les correctifs de compatibilité PIDFD (versions rétroportées disponibles dans les noyaux communs Android 4.9, 4.14 et 4.19).
- Pour les appareils à faible RAM, incluez des cgroups de mémoire.
Le noyau doit être compilé avec les paramètres de configuration suivants:
CONFIG_PSI=y
Configurer lmkd dans Android 11
La stratégie d'élimination de la mémoire dans Android 11 est compatible avec les boutons de réglage et les valeurs par défaut listés ci-dessous. Ces fonctionnalités fonctionnent aussi bien sur les appareils hautes performances que sur ceux à faible RAM.
Propriété | Utiliser | Par défaut | |
---|---|---|---|
Hautes performances | Faible RAM | ||
ro.lmk.psi_partial_stall_ms |
Seuil de blocage PSI partiel, en millisecondes, pour le déclenchement d'une notification de mémoire insuffisante. Si l'appareil reçoit des notifications de pression de la mémoire trop tard, réduisez cette valeur pour déclencher des notifications plus tôt. Si les notifications de pression de la 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 |
Seuil complet de blocage PSI, en millisecondes, pour le déclenchement des notifications critiques de la mémoire. Si l'appareil reçoit des notifications critiques de pression sur la mémoire trop tard, diminuez cette valeur pour déclencher des notifications plus tôt. Si les notifications de pression de mémoire critique se déclenchent inutilement, augmentez cette valeur pour rendre l'appareil moins sensible au bruit. | 700 |
|
ro.lmk.thrashing_limit |
Nombre maximal de refaults de l'ensemble de travail en pourcentage de la taille totale du cache de pages basé sur des fichiers. Les erreurs de remplacement du workingset supérieures à cette valeur signifient que le système est considéré comme épuisant son cache de pages. Si les performances de l'appareil sont affectées en cas de pression de la mémoire, diminuez la valeur pour limiter le thrashing. Si les performances de l'appareil sont arrêtées inutilement pour des raisons de fragmentation, augmentez la valeur pour autoriser davantage de fragmentation. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
La dépréciation du seuil de thrashing, exprimée en pourcentage du seuil d'origine utilisé pour abaisser le seuil lorsque le système ne se rétablit pas, même après un arrêt. Si le balayage continu génère des arrêts inutiles, diminuez la valeur. Si la réponse au balayage continu après un arrêt est trop lente, augmentez la valeur. | 10 |
50 |
ro.lmk.swap_util_max |
Quantité maximale de mémoire échangée, exprimée en pourcentage de la mémoire totale pouvant être échangée. Lorsque la mémoire d'échange dépasse cette limite, cela signifie que le système a échangé la majeure partie de sa mémoire d'échange et qu'il est toujours sous pression.
Cela peut se produire lorsque des allocations non interchangeables génèrent une pression sur la mémoire qui ne peut pas être soulevée par les échanges, car la majeure partie de la mémoire interchangeable 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 lorsque la mémoire est sollicitée alors que l'utilisation de l'échange est élevée et que le niveau d'échange sans frais ne descend pas à ro.lmk.swap_free_low_percentage , diminuez la valeur pour limiter l'utilisation des échanges. |
100 |
100 |
Les anciens boutons de réglage suivants fonctionnent également avec la nouvelle stratégie d'arrêt.
Propriété | Utiliser | Par défaut | |
---|---|---|---|
Hautes performances | Faible RAM | ||
ro.lmk.swap_free_low_percentage |
Niveau d'espace d'échange libre, exprimé 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 d'échange. Si "lmkd" arrête le processus alors qu'il y a trop d'espace dans l'espace de swap, diminuez le pourcentage. Si les arrêts de l'lmkd se produisent trop tard, ce qui permet aux arrêts 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 |