Android 17 et versions ultérieures sont compatibles avec le daemon PMGD (Process Memory Guardian Daemon), qui protège l'état du système et l'expérience utilisateur en gérant de manière proactive l'utilisation de la mémoire par processus. Le daemon améliore la stabilité globale de l'appareil en appliquant des limites de mémoire à des processus cibles spécifiques, et en vérifiant que les fuites ou les pics de mémoire isolés n'entraînent pas de dégradation des performances à l'échelle du système.
Alors que les robots tueurs de mémoire conventionnels n'agissent que lorsque l'ensemble du système est sous pression, PMGD adopte une approche plus précise. Pour ce faire, le daemon atteint ce
en surveillant les valeurs de mémoire du groupe de contrôle v2 pour ses processus cibles.
Lorsqu'un processus ciblé dépasse ses limites de mémoire configurées, pmgd gère les violations de limite en enregistrant les atomes de mémoire Statsd avant de mettre fin au processus.
Fonctionnement
Le daemon utilise inotify pour écouter les événements de pression de la mémoire (en particulier l'activité de mémoire élevée à l'aide de memory.events). Lorsqu'un processus surveillé déclenche un événement de mémoire, pmgd effectue les actions suivantes :
- Vérification de la mémoire anonyme : évalue la mémoire anonyme du processus. Si elle dépasse la valeur
anon_limit_in_mbconfigurée,pmgdarrête immédiatement le processus. - Période d'attente de récupération : si la mémoire anonyme est inférieure à la limite de mémoire anonyme spécifiée,
pmgdattend une période de grâce de récupération du système (reclaim_wait_time_secs). - Évaluation de la mémoire après récupération : si la valeur
memory.currentdu processus cible reste supérieure ou égale àmemory.highaprès la période de grâce, ou si la mémoire anonyme dépasseanon_limit_in_mb,pmgdarrête immédiatement le processus.
Cette opération est effectuée en continu jusqu'à ce que le processus soit arrêté ou que la récupération sur le processus réduise son utilisation de la mémoire en dessous des limites de mémoire spécifiées.
Fonctionnalités de santé du système
- Limitation du taux de redémarrage : pour éviter les boucles de démarrage ou les plantages persistants,
pmgdsuit les arrêts de processus dans/data/misc/pmgd/history.json. Le daemon limite les processus à un seul arrêt initié parpmgdpar redémarrage de l'appareil.
Configuration SELinux
La capacité de PMGD à surveiller les processus est limitée par la règle SELinux. Si vous configurez PMGD pour surveiller un processus dont le domaine n'est pas autorisé par la règle, tel qu'un processus système spécifique au fournisseur, PMGD ne peut pas le surveiller et vous pouvez voir des refus SELinux dans logcat.
Pour autoriser PMGD à surveiller les processus dans des domaines supplémentaires, vous devez étendre les autorisations de PMGD en mettant à jour la règle SELinux spécifique à votre appareil pour PMGD.
Voici un exemple de fichier device/<vendor>/<device>/sepolicy/pmgd.te
qui ajoute l'accès à un nouveau domaine :
# Allow pmgd to access vendor_system_apps
r_dir_file(pmgd, vendor_system_apps)
Pour en savoir plus sur l'écriture d'une règle spécifique à un appareil, consultez Implémenter SELinux.
Configuration définie par le fournisseur
La configuration de PMGD est gérée par le fournisseur et configurée par un fichier JSON obligatoire /vendor/etc/pmgd/config.json. Ce fichier répertorie les processus à suivre,
leur profil de limite de mémoire configuré (à l'aide de
profils de tâches cgroup),
et la limite de mémoire anonyme stricte en mégaoctets.
Champs de configuration du fournisseur
La configuration JSON fournie est une liste de processus et de leurs limites, définies par les champs suivants :
| Champ | Type | Obligatoire | Description | Par défaut |
|---|---|---|---|---|
target_cmd |
Chaîne | Oui | Nom de la commande du processus cible à surveiller, par exemple system_server. |
N/A |
uid |
Nombre entier | Non | ID utilisateur (UID) du processus. En cas d'omission, pmgd applique
la règle globalement à tout processus correspondant à target_cmd. |
N/A |
reclaim_wait_time_secs |
Nombre entier | Non | Période de grâce en secondes pendant laquelle le système récupère de la mémoire avant de réévaluer la limite de mémoire. | 5 |
mem_limit_profile |
Chaîne | Oui | Nom du profil de tâche cgroup qui définit `memory.high`. Il permet de définir la limite de mémoire du processus. | N/A |
anon_limit_in_mb |
Nombre entier | Oui | Limite de mémoire anonyme ultime en mégaoctets. Si l'utilisation de la mémoire anonyme
dépasse cette valeur, pmgd arrête rapidement le
processus. |
N/A |
additional_task_profiles |
Liste de chaînes | Non | Liste de tous les profils de tâches supplémentaires que pmgd applique au
processus au début de la surveillance. |
Liste vide |
Voici un exemple de configuration du profil de tâche cgroup dans vendor/etc/task_profiles.json :
{
"Attributes": [
...
{
"Name": "MemHigh",
"Controller": "memory",
"File": "memory.high"
}
],
"Profiles": [
{
"Name": "SystemServerMemoryHighLimit",
"Actions": [
{
"Name": "SetAttribute",
"Params":
{
"Name": "MemHigh",
"Value": "1080M"
}
}
]
}
]
}
Voici un exemple de configuration de PMGD dans vendor/etc/pmgd/config.json :
{
"targets": [
{
"target_cmd": "system_server",
"uid": 1000,
"reclaim_wait_time_secs": 5,
"mem_limit_profile": "SystemServerMemoryHighLimit",
"anon_limit_in_mb": 300
}
]
}