Android 17 et versions ultérieures sont compatibles avec le limiteur de mémoire, un service système qui surveille et limite l'utilisation de la mémoire des processus d'application à l'aide de cgroup v2 Linux. Le limiteur de mémoire empêche les applications individuelles de consommer trop de mémoire système, ce qui réduit la pression sur la mémoire à l'échelle du système et empêche l'arrêt agressif des processus critiques en cas de mémoire insuffisante (OOM).
Mécanisme
Le limiteur de mémoire s'intègre au service Activity Manager (AMS) pour suivre les événements du cycle de vie des processus et les changements d'état. Le limiteur de mémoire applique les limites de mémoire à l'aide du système de fichiers cgroup v2 du noyau Linux.
Pour utiliser le limiteur de mémoire, le noyau de l'appareil doit être compatible avec cgroup v2 et le contrôleur memory. Le service repose spécifiquement sur les attributs suivants :
memory.high- Limite flexible. Lorsqu'elle est dépassée, le processus est limité et le noyau tente de récupérer de la mémoire.
memory.swap.max- Limite la quantité d'espace d'échange que le processus peut utiliser.
Impact sur les applications
Les applications qui ne dépassent pas leurs limites de mémoire ne sont pas affectées par le limiteur de mémoire.
Lorsqu'une application dépasse sa limite memory.high, le noyau supprime la mémoire sauvegardée de l'application et échange sa mémoire anonyme pour que l'application reste dans la limite. En raison de la suppression et de l'échange, l'application peut s'exécuter plus lentement.
À l'extrême, si l'application continue d'allouer de la mémoire anonyme et que l'appareil manque d'espace d'échange, l'application peut ne pas parvenir à allouer de la mémoire et risque donc de planter.
Surveillance des processus
Par défaut, le limiteur de mémoire surveille les processus d'application (UID >= 10000). Les processus système sont généralement exemptés pour aider à vérifier la stabilité du système de base.
Le limiteur de mémoire attribue des limites de mémoire en fonction de l'état du processus :
Les processus visibles sont perceptibles par l'utilisateur, comme les activités de premier plan, les services de premier plan ou d'autres états perceptibles.
Les processus non visibles sont des processus d'arrière-plan qui n'interagissent pas avec l'utilisateur et ne sont pas visibles par lui.
Le tableau suivant mappe des états de processus spécifiques à des limites de mémoire :
| État du processus | Limite de mémoire |
|---|---|
PERSISTENT | Pas de restriction |
PERSISTENT_UI | Pas de restriction |
TOP | Visible |
BOUND_TOP | Visible |
FOREGROUND_SERVICE | Non visible |
BOUND_FOREGROUND_SERVICE | Non visible |
IMPORTANT_FOREGROUND | Visible |
IMPORTANT_BACKGROUND | Non visible |
TRANSIENT_BACKGROUND | Non visible |
BACKUP | Non visible |
SERVICE | Non visible |
RECEIVER | Non visible |
TOP_SLEEPING | Visible |
HEAVY_WEIGHT | Non visible |
HOME | Non visible |
LAST_ACTIVITY | Non visible |
CACHED_ACTIVITY | En cache |
CACHED_ACTIVITY_CLIENT | En cache |
CACHED_RECENT | En cache |
CACHED_EMPTY | En cache |
Dans l'état mis en cache, les processus sont figés, puis récupérés au maximum.
Lorsqu'un processus dépasse sa limite memory.high attribuée, le limiteur de mémoire détecte l'événement et peut déclencher des actions de débogage, telles que la capture d'un profil de mémoire ou la journalisation d'une anomalie dans statsd.
Configuration
Configurez le limiteur de mémoire à l'aide d'un fichier XML situé sur la partition vendor. La configuration vous permet d'ajuster les limites de mémoire absolues en fonction des contraintes de mémoire spécifiques de l'appareil.
Chemin d'accès au fichier :
/vendor/etc/memory-limiter-config.xmlConfiguration par défaut : si le fichier de configuration est introuvable, illisible ou non valide, le limiteur de mémoire est désactivé.
Format XML
Le fichier de configuration suit le schéma défini dans memory-limiter-config.xsd. Le fichier vous permet de définir plusieurs ensembles de limites. Le service choisit la meilleure correspondance en fonction de la RAM disponible de l'appareil. Toutes les valeurs de mémoire sont définies en mébioctets (Mio).
<MemoryLimiterConfig>
<version>1</version>
<configList>
<limitSet>
<!-- Limits for a phone with at least 14G of ram: 8G/4G/4G/4G -->
<minimumRequiredMemTotal>14336</minimumRequiredMemTotal>
<memVisible>8192</memVisible>
<memNotVisible>4096</memNotVisible>
<swapVisible>4096</swapVisible>
<swapNotVisible>4096</swapNotVisible>
</limitSet>
</configList>
</MemoryLimiterConfig>
version- Entier positif identifiant la version de configuration. Doit être égal à 1.
minimumRequiredMemTotal- Mémoire système disponible minimale requise pour que cet ensemble de limites soit valide.
memVisible- Limite de mémoire (
memory.high) autorisée pour les processus visibles. memNotVisible- Limite de mémoire (
memory.high) autorisée pour les processus non visibles. swapVisible- Limite d'échange (
memory.swap.max) autorisée pour les processus visibles. swapNotVisible- Limite d'échange (
memory.swap.max) autorisée pour les processus non visibles.
Modifier la configuration
Pour modifier les limites à l'échelle du système, procédez comme suit :
- Modifiez
/vendor/etc/memory-limiter-config.xml. - Redémarrez l'appareil ou redémarrez
system_serverpour que les modifications prennent effet.
Commandes shell
La commande am memory-limiter vous permet, ainsi qu'aux développeurs, d'interagir avec le service au moment de l'exécution pour le développement et les tests :
am memory-limiter <SUB-COMMAND>état
La sous-commande status indique l'état opérationnel du limiteur de mémoire :
adb shell am memory-limiter statusExemple de résultat :
Memory limiter
enabled monitoring=true ignored=none
visibleMem=1948MB visibleSwap=974MB
notVisibleMem=974MB notVisibleSwap=487MB
started=36 watched=36 watch-failed=0
events=0 processes=36 process-hwm=36
Les champs clés du résultat incluent les suivants :
monitoring- Indique si le limiteur surveille activement les processus.
visibleMemetnotVisibleMem- Indiquent les limites de mémoire absolues calculées pour chaque état.
events- Nombre de fois qu'un processus a dépassé sa limite.
processes- Nombre de processus surveillés.
ignorer
La sous-commande ignore exclut temporairement un UID ou tous les processus de la limitation. Cette action est utile pour les tests de performances ou lorsque vous autorisez une application spécifique à dépasser ses limites.
adb shell am memory-limiter ignore 10087 // Ignore a specific UIDadb shell am memory-limiter ignore all // Ignore all processes (effectively disables limiting)adb shell am memory-limiter ignore none // Resume normal operation
manuel
La sous-commande manual remplace les limites calculées pour un processus spécifique (par ID de processus ou PID) par une valeur absolue personnalisée en mégaoctets (Mo) :
adb shell am memory-limiter manual 1234 1024 // Set a 1024 MB limit for PID 1234adb shell am memory-limiter manual 1234 none // Remove the manual override for PID 1234
Les remplacements manuels ne s'appliquent qu'au cycle de vie du processus. Si le processus redémarre, il revient aux limites par défaut en fonction de son état.