Capturez une empreinte de la mémoire pour voir quels objets de votre application utilisent de la mémoire au moment de la capture et identifier les fuites de mémoire ou le comportement d'allocation de mémoire qui entraîne des saccades, des blocages et même des plantages de l'application. Il est particulièrement utile de créer des vidages de tas après une longue session utilisateur, car ils peuvent afficher des objets qui restent en mémoire alors qu'ils ne devraient plus y être.
Cette page décrit les outils fournis par Android Studio pour collecter et
analyser les empreintes de la mémoire. Vous pouvez également inspecter la mémoire utilisée par votre application à partir de la ligne de commande avec dumpsys
et examiner les événements de récupération de mémoire (GC) dans Logcat.
Pourquoi profiler la mémoire d'une application ?
Android fournit un environnement mémoire géré. Lorsqu'Android détermine que votre application n'utilise plus certains objets, le récupérateur libère la mémoire inutilisée pour la rendre disponible. La façon dont Android détecte la mémoire inutilisée est constamment améliorée, mais toutes les versions ont un point commun : à un moment donné, le système doit suspendre brièvement votre code. La plupart du temps, ces pauses sont imperceptibles. Toutefois, si votre application alloue de la mémoire plus vite que le système ne peut la collecter, votre application peut être retardée pendant que le collecteur libère suffisamment de mémoire pour satisfaire vos allocations. Ce retard peut entraîner le saut d'images de votre application une lenteur visible.
En cas de fuite, votre application peut monopoliser la mémoire en arrière-plan, même si elle ne présente pas de ralentissement visible. Ce comportement peut affecter les performances du reste de la mémoire du système, en imposant des événements de récupération de mémoire inutiles. Le système devra éventuellement mettre fin au processus de votre application pour récupérer la mémoire. Ensuite, lorsque l'utilisateur revient dans votre application, le processus de l'application doit redémarrer. complètement.
Pour en savoir plus sur les pratiques de programmation permettant de réduire l'utilisation de mémoire de votre application, consultez la page Gérer la mémoire de votre application.
Présentation de l'empreinte de la mémoire
Pour capturer une empreinte de la mémoire, Sélectionnez la tâche Analyze Memory Usage (Heap Dump) (Analyser l'utilisation de la mémoire (vidage de la mémoire)). (utilisez Profiler: run 'app' as debuggable (complete data)) pour capturer un tas de mémoire vide. Lors du vidage du tas de mémoire, la quantité de mémoire Java peut augmenter temporairement. C'est normal, car l'opération est effectuée dans le même processus que votre application et nécessite de la mémoire pour collecter les données. Une fois l'empreinte de la mémoire capturée, les informations suivantes s'affichent :
La liste des classes affiche les informations suivantes:
- Allocations : le nombre d'allocations dans le segment de mémoire.
Taille native: quantité totale de mémoire native utilisée par ce type d'objet (en octets). Vous verrez ici de la mémoire pour certains objets alloués en Java, car Android utilise la mémoire native pour certaines classes de framework, telles que
Bitmap
Taille superficielle : quantité totale de mémoire Java utilisée par ce type d'objet (en octets).
Taille conservée : volume total de mémoire conservé pour toutes les instances de cette classe (en octets).
Utilisez le menu des segments de mémoire pour n'afficher que certains segments de mémoire:
- Tas de mémoire de l'application (par défaut) : tas principal sur lequel votre application alloue de la mémoire.
- Tas de mémoire de l'image: image de démarrage du système, contenant les classes préchargées. pendant le démarrage. Ces allocations ne sont jamais déplacées ni supprimées.
- Tas de mémoire de Zygote : tas de mémoire en copie sur écriture, à partir duquel les processus d'application sont dupliqués dans le système Android.
Utilisez le menu déroulant "Organisation" pour choisir comment organiser les allocations :
- Trier par classe (par défaut) : regroupe toutes les allocations par nom de classe.
- Trier par package : pour regrouper les allocations par nom de package.
Utilisez le menu déroulant des cours pour filtrer les groupes de cours :
- Toutes les classes (par défaut): affiche toutes les classes, y compris celles des bibliothèques et les dépendances.
- Show activity/fragment leaks (Afficher les fuites d'activité/de fragment) : affiche les classes qui provoquent des fuites de mémoire.
- Show project classes (Afficher les classes du projet) : affiche uniquement les classes définies par votre projet.
Cliquez sur le nom d'une classe pour ouvrir le volet Instance. Chaque instance listée inclut les éléments suivants :
- Profondeur : le plus petit nombre de sauts entre une racine GC et l'instance sélectionnée.
- Volume de mémoire native : la mémoire native utilisée par cette instance. Cette colonne est visible uniquement sur Android 7.0 ou version ultérieure.
- Taille superficielle : la mémoire Java utilisée par cette instance.
- Taille conservée: la taille de mémoire dominée par cette instance (conformément aux arborescence dominante).
Cliquez sur une instance pour afficher les détails de l'instance, y compris ses champs et ses références. Les types de champs et de références courants sont les types structurés
,
tableaux
,
et les types de données primitifs
en Java. Effectuez un clic droit sur un champ ou une référence pour accéder à l'instance associée ou
dans le code source.
- Champs : affiche tous les champs de cette instance.
- Références: affiche toutes les références à l'objet mis en surbrillance dans le champ Instance.
Trouver des fuites de mémoire
Pour filtrer rapidement les classes pouvant être associées à des fuites de mémoire, ouvrez le menu déroulant des classes et sélectionnez Afficher les fuites d'activité/de fragment. Android Studio affiche les classes qui, selon lui, indiquent des fuites de mémoire pour les instances Activity
et Fragment
de votre application. Vous pouvez filtrer les types de données suivants :
- Instances
Activity
détruites, mais qui sont toujours référencées. - Instances
Fragment
qui n'ont pas deFragmentManager
valide, mais qui sont toujours référencées.
Sachez que le filtre peut générer des faux positifs dans les cas suivants : situations suivantes:
- Un
Fragment
a été créé, mais n'a pas encore été utilisé. - Un
Fragment
est mis en cache, mais ne fait pas partie d'unFragmentTransaction
.
Pour rechercher plus manuellement des fuites de mémoire, parcourez les listes de classes et d'instances pour trouver les objets dont la taille conservée est élevée. Recherchez les fuites de mémoire causées par des éléments suivants:
- Références de longue durée à
Activity
,Context
,View
,Drawable
et d'autres objets susceptibles de contenir une référence au conteneurActivity
ouContext
. - Classes internes non statiques, telles qu'une
Runnable
, qui peuvent contenir une instanceActivity
. - Des caches qui maintiennent des objets plus longtemps que nécessaire.
Lorsque vous détectez des fuites de mémoire potentielles, utilisez les onglets Champs et Références dans Détails de l'instance pour accéder à la ligne d'instance ou de code source qui vous intéresse.
Déclencher des fuites de mémoire à des fins de test
Pour analyser l'utilisation de la mémoire, vous devez mettre à l'épreuve le code de votre application et essayer de forcer l'apparition des fuites de mémoire. L'une des manières de procéder consiste à exécuter votre application pendant une période prolongée avant d'inspecter le tas de mémoire. Le volume accumulé par les fuites peut les hisser au sommet des allocations du tas de mémoire. Cependant, plus la fuite est faible, plus l'exécution de l'application prend de temps pour la voir.
Vous pouvez également déclencher une fuite de mémoire en appliquant l'une des méthodes suivantes :
- Faites pivoter l'appareil du mode Portrait au mode Paysage avant de revenir en arrière.
dans différents états d'activité. La rotation de l'appareil peut souvent entraîner la fuite d'un objet
Activity
,Context
ouView
, car le système recrée l'objetActivity
. Si un autre élément de votre application maintient une référence à l'un de ces objets, le système ne peut pas récupérer la mémoire correspondante. - Basculez entre votre application et une autre application dans différents états d'activité. Par exemple, accédez à l'écran d'accueil, puis revenez à votre application.
Exporter et importer un enregistrement d'empreinte de la mémoire
Vous pouvez exporter et importer un fichier de vidage de tas à partir de l'onglet Enregistrements précédents du profileur. Android Studio enregistre l'enregistrement en tant que fichier .hprof
.
Vous pouvez également utiliser un autre analyseur de fichiers .hprof
, comme
jhat
vous devez convertir le fichier .hprof
au format Android en Java SE
Format de fichier .hprof
. Pour convertir le format de fichier, utilisez l'outil hprof-conv
fourni dans le répertoire {android_sdk}/platform-tools/
. Exécuter l'hprof-conv
avec deux arguments: le nom de fichier .hprof
d'origine et l'emplacement de
écrire le fichier .hprof
converti, en incluant le nouveau nom de fichier .hprof
. Exemple :
hprof-conv heap-original.hprof heap-converted.hprof