L'optimisation de la mémoire est essentielle pour offrir des expériences de jeu stables et performantes sur Android. Ce guide explique pourquoi l'efficacité de la mémoire est importante, comment le système d'exploitation Android gère et applique les limites de mémoire des processus, et les nouveaux seuils exposés dans la Google Play Console pour vous aider à surveiller et à améliorer la qualité technique de votre jeu.
L'importance de l'optimisation de la mémoire
L'optimisation de la mémoire de votre jeu est essentielle pour fidéliser les joueurs, étendre la compatibilité des appareils et respecter les normes de qualité de la plate-forme :
- Prévention des démarrages à froid (expérience utilisateur et fidélisation) : lorsqu'un joueur quitte temporairement votre jeu (par exemple, pour répondre à une notification ou consulter un message), le système d'exploitation place le processus du jeu en arrière-plan. Si l'espace mémoire utilisé en arrière-plan du jeu est trop élevé, le Low Memory Killer (LMK) du système donne la priorité à l'arrêt du processus du jeu pour récupérer de la RAM pour les tâches de premier plan. La prochaine fois que l'utilisateur reprendra le jeu, au lieu d'une reprise à chaud fluide et instantanée, le jeu devra subir un long démarrage à froid, en rechargeant complètement les éléments graphiques, audio et binaires du moteur de jeu à partir du stockage. En maintenant une faible utilisation de la mémoire en arrière-plan, vous évitez ces arrêts silencieux en arrière-plan, vous préservez l'état de l'utilisateur et vous vous assurez que les joueurs peuvent reprendre leur session immédiatement. Pour en savoir plus sur le comportement du LMK du système, consultez le guide Android Vitals – Low memory killers.
- Stabilité de l'écosystème et de l'appareil : une utilisation inefficace de la mémoire et les fuites de mémoire dégradent l'état général du système. Lorsque la mémoire système est insuffisante, le système est soumis à une forte pression, ce qui entraîne une baisse de la fréquence d'images, des à-coups dans l'interface utilisateur et des problèmes audio. Si la pression sur la mémoire est trop forte, le Low Memory Killer (LMK) du système arrête de manière agressive les processus en arrière-plan, ce qui oblige les autres applications à subir des démarrages à froid lents et à perdre l'état de l'utilisateur lorsque les joueurs passent d'une tâche à l'autre.
- Arrêts au niveau de la plate-forme : à partir d'Android 17 (niveau d'API 37), le système est plus proactif dans l'arrêt des processus qui utilisent trop de mémoire. Si l'encombrement de votre jeu est trop élevé, l'OS peut arrêter son processus de manière abrupte sans générer de trace de la pile standard.
- Compatibilité des appareils : alors que les appareils phares disposent de 12 à 16 Go de RAM, une grande partie de l'audience mondiale des jeux utilise des appareils avec 4 ou 6 Go de RAM. Une gestion appropriée de la mémoire garantit que votre jeu reste accessible et réactif sur tous les niveaux de matériel sans nécessiter de packages d'éléments complexes et distincts.
Comprendre la mémoire dans Android
Pour concevoir des stratégies efficaces de budgétisation de la mémoire, les développeurs doivent comprendre comment la plate-forme Android gère la mémoire physique et comment elle mesure l'encombrement actif de leur jeu.
Concepts fondamentaux de la mémoire Android
Pour connaître les concepts fondamentaux concernant la gestion de la mémoire au niveau de la plate-forme, consultez la documentation officielle Présentation de la gestion de la mémoire. Cette ressource couvre quatre domaines architecturaux :
- Présentation de la mémoire : Android utilise la pagination et la mise en correspondance de mémoire (mmap) pour gérer la RAM. Il ne prend pas en charge de fichier d'échange traditionnel sur disque. Il s'appuie plutôt sur la compression de pages (à l'aide de zRAM) et la récupération de pages pour libérer de la mémoire physique.
- Allocation de mémoire entre les processus : Android partage la RAM sur l'ensemble du système. Il attribue des tas de mémoire spécifiques pour l'exécution de la machine virtuelle Dalvik ou ART, tout en permettant aux environnements de développement natifs (tels que les moteurs de jeu C++) de demander de la mémoire au tas de mémoire du système natif.
- Gestion de la mémoire des applications : fonctionnant sous un modèle multiprocessus, Android s'attend à ce que les applications surveillent leur état de cycle de vie de manière dynamique et libèrent volontairement les ressources inutiles (telles que les graphiques et les bitmaps non mis en cache) pour préserver l'état du système.
- Présentation des processus et des threads : le système catégorise les processus dans une hiérarchie en fonction de leur visibilité et de leur importance perçues par l'utilisateur, ce qui détermine les processus qui sont maintenus en vie et ceux qui sont arrêtés en premier en cas de mémoire insuffisante.
Métrique d'espace mémoire utilisé total
Le Memory Limiter d'Android 17 au niveau de la plate-forme évalue la consommation des processus à l'aide de l'encombrement total de la mémoire plutôt que de la taille résidente totale (RSS) ou de la taille de la mémoire virtuelle.
Encombrement total de la mémoire = RSS anonyme (RssAnon) + échange non compressé (VmSwap)
Pour éviter que les jeux ne dépassent les limites appliquées par la plate-forme, les développeurs doivent comprendre exactement ce que représentent ces métriques au niveau du système. Pour en savoir plus sur ces métriques, les allocations de RAM physique et la gestion des pages sauvegardées dans des fichiers, consultez Comprendre les métriques RSS et d'échange dans le guide Surveiller l'utilisation de la mémoire.
Contraintes de mémoire
Pour maintenir la stabilité du système et s'assurer que les applications ne consomment pas de ressources excessives, la plate-forme Android applique des limites de mémoire aux processus en cours d'exécution.
Memory Limiter dans Android 17 et versions ultérieures
Android 17 et versions ultérieures appliquent des limites de mémoire strictes par application à l'aide de Linux cgroup v2 pour empêcher les applications individuelles de provoquer une instabilité à l'échelle du système. Pour en savoir plus sur l'implémentation technique, consultez le guide AOSP Memory Limiter et l'article de blog Priorité à l'efficacité de la mémoire : étapes essentielles pour Android 17.
- Mécanisme : le Memory Limiter surveille tous les processus d'application et
attribue dynamiquement des limites en fonction de l'état du cycle de vie du processus :
- Processus visibles (premier plan) : les processus d'application qui affichent actuellement une interface utilisateur sont censés exécuter un ensemble de travail de ressources plus important et bénéficient d'une limite plus généreuse.
- Processus non visibles (arrière-plan ou services) : les processus d'application qui effectuent un travail actif sans afficher d'interface utilisateur sont limités à un budget plus strict et plus restrictif.
- Attributs du noyau : le service repose sur deux attributs principaux :
memory.high: limite souple. Lorsqu'elle est dépassée, le noyau limite le processus et tente de récupérer de la mémoire de manière agressive. Cette récupération peut entraîner une dégradation des performances du jeu.memory.swap.max: applique une limite stricte à l'espace d'échange ou zRAM que le processus peut utiliser.
- Comportement d'arrêt : si un processus continue d'allouer de la mémoire anonyme
au-delà de
memory.highet épuise sa capacité d'échange, les allocations échouent et le système d'exploitation arrête silencieusement le processus. Cet arrêt est enregistré à l'aide deApplicationExitInfosous le motif de sortie Memory Limiter (disponible à partir d'Android 17, 26Q4).
Surveiller l'utilisation de la mémoire
Pour optimiser efficacement la mémoire de votre jeu, vous devez d'abord comprendre comment la plate-forme Android mesure son encombrement. Android 17 met à jour la métrique d'application de la mémoire pour suivre la somme du RSS anonyme (RssAnon) et de l'échange non compressé (VmSwap), à l'exclusion de la mémoire sauvegardée dans des fichiers ou privée du GPU. Ce guide explique comment tirer parti des outils au niveau du système tels que Perfetto et meminfo, implémenter des API de diagnostic telles que ProfilingManager et onTrimMemory, et extraire des allocations de mémoire précises dans Unity et Unreal Engine. Découvrez comment profiler précisément votre jeu et éviter les à-coups de performances associés à l'interrogation traditionnelle de la mémoire d'exécution.
Pour en savoir plus, consultez Surveiller l'utilisation de la mémoire.
Stratégies de réduction de la mémoire
Bien que les moteurs de jeu simplifient le développement multiplate-forme, leur gestion par défaut de la mémoire peut déclencher des limites de mémoire au niveau du système d'exploitation. Cette page décrit les étapes pratiques d'optimisation spécialement conçues pour Unity et Unreal Engine. Découvrez pourquoi le recours à onTrimMemory basé sur Java peut entraîner des blocages dans Unity et comment utiliser des rappels de cycle de vie natifs à la place. Vous découvrirez également les principales optimisations au niveau des éléments, telles que l'utilisation de la compression de texture ASTC 8x8 et la configuration des déchargements d'éléments, pour que votre jeu fonctionne correctement sur tous les niveaux de matériel.