Comprendre et résoudre les problèmes de mémoire Android

La mémoire est une ressource essentielle et limitée sur les appareils Android. En tant que développeur de la plate-forme Android ou OEM, il est essentiel de comprendre le fonctionnement de la mémoire à tous les niveaux (de l'environnement d'exécution Java au noyau Linux) pour créer un système performant et stable.

Ce guide fournit une présentation complète de l'architecture de la mémoire Android, des outils d'analyse disponibles et des exercices pratiques pour vous aider à identifier et à résoudre les problèmes liés à la mémoire.

Objectifs

Après avoir suivi ce guide, vous saurez :

  • Expliquer les concepts fondamentaux de la mémoire Android, y compris le modèle de processus Zygote et les fichiers mappés en mémoire.
  • Différencier la taille de l'ensemble résident (RSS), la taille de l'ensemble proportionnel (PSS) et la taille de l'ensemble unique (USS).
  • Utilisez des outils de ligne de commande standards tels que dumpsys meminfo et showmap pour évaluer rapidement l'utilisation de la mémoire.
  • Capturez et analysez les empreintes de la mémoire Java à l'aide d'AHAT pour détecter les fuites et les allocations excessives.
  • Utilisez Perfetto et heapprofd pour profiler la mémoire Java et la mémoire native sur l'ensemble du système.
  • Comprendre les indicateurs de pression de la mémoire à l'échelle du système, tels que les informations sur les blocages de pression (PSI), et surveiller l'activité du tueur de mémoire faible (LMK).
  • Observez l'activité de récupération au niveau du kernel, y compris l'échange ZRAM et l'éviction du cache de page.

Structure du guide

Ce guide est organisé en plusieurs sections, conçues pour être lues de manière séquentielle :

  1. Concepts fondamentaux : principes techniques de base de la mémoire Android.
  2. Outils d'évaluation rapide : utilisation de meminfo, showmap et procstats pour un tri rapide.
  3. Analyser la mémoire Java : Présentations détaillées du tas de mémoire Java avec AHAT.
  4. Bitmaps et mémoire : comprendre l'impact des images sur la RAM et utiliser des outils pour les profiler.
  5. Analyser la mémoire native : profiler la mémoire C/C++ avec Perfetto et heapprofd.
  6. WebView et mémoire : comprendre l'architecture multiprocessus et l'espace mémoire utilisé par les WebViews.
  7. Le code de l'application est en mémoire : comprendre l'impact du chargement des classes et du gonflement des fichiers dex sur la RAM.
  8. Threads et mémoire : analyse du coût des piles de threads natifs.
  9. Localité et performances de la mémoire : comprendre comment les modèles d'accès aux données affectent les performances du processeur.
  10. Liaisons de services et états des processus : comprendre l'impact des dépendances entre processus sur les scores OOM.
  11. Dépannage à l'échelle du système : surveillance de l'indicateur PSI, du LMK, de l'échange ZRAM et de l'éviction du cache de pages.
  12. Récupération de mémoire : éviction et échange : comprendre memcg, la charge et la récupération proactive avec memory.reclaim.
  13. Interaction entre kswapd et lmkd : comprendre comment kswapd et lmkd fonctionnent ensemble sous pression.
  14. Renvoyer les pages de mémoire au système d'exploitation : utiliser madvise et posix_fadvise pour renvoyer les pages de tas de mémoire et les pages de cache de fichiers inutilisées au noyau.
  15. Maintenir l'activité en arrière-plan avec un processus léger : déplacer les services d'arrière-plan et les workers vers un processus dédié afin que l'UI et la mémoire graphique ne soient pas maintenues à une priorité élevée.

Prérequis et environnement

Ce guide présente des workflows de référence, des données de benchmark et des études de cas montrant comment diagnostiquer et résoudre les problèmes de mémoire Android.

  • Outils d'analyse : les techniques de ce guide utilisent principalement des outils de performances Android standards, y compris Perfetto, dumpsys meminfo, showmap et AHAT.
  • Droits racine : certains workflows de diagnostic au niveau du système (comme l'inspection de la pression de la mémoire du noyau ou des compteurs PMU matériels) nécessitent des droits racine élevés (adb root) sur un appareil userdebug ou un build d'émulateur.

Commencer ici : Concepts fondamentaux