L'enregistrement des allocations Java/Kotlin vous aide à identifier les schémas de mémoire indésirables susceptibles d'entraîner des problèmes de performances. Le profileur peut afficher les informations suivantes concernant les allocations d'objets :
- Les types d'objets alloués et l'espace qu'ils occupent.
- La trace de la pile pour chaque allocation, avec identification du thread.
- Heure à laquelle les objets ont été libérés.
Vous devez enregistrer les allocations de mémoire lors d'interactions utilisateur normales et extrêmes pour identifier précisément les points où votre code alloue trop d'objets en peu de temps, ou alloue les objets produisant les fuites. Découvrez pourquoi vous devriez profiler la mémoire de votre application.
Enregistrer des allocations Java/Kotlin
Pour enregistrer des allocations Java/Kotlin, sélectionnez la tâche Suivre la consommation de mémoire (allocations Java/Kotlin) dans l'onglet Accueil du profileur. Notez que vous avez besoin d'une application débogable (utilisez Profiler : exécuter "app" en tant que débogable (données complètes)) pour enregistrer les allocations Java/Kotlin.
Par défaut, Android Studio capture toutes les allocations d'objets en mémoire. Si votre application alloue de nombreux objets, elle risque d'être visiblement ralentie pendant le profilage. Pour améliorer les performances lors du profilage, accédez au menu déroulant Suivi de l'allocation et sélectionnez Échantillonné au lieu de Complet. Lors de l'échantillonnage, le profileur collecte les allocations d'objets en mémoire à intervalles réguliers.
Pour forcer la récupération de mémoire pendant l'enregistrement, cliquez sur l'icône en forme de poubelle .
Présentation des allocations Java/Kotlin
Une fois l'enregistrement arrêté, les informations suivantes s'affichent :
- La chronologie des événements affiche les états d'activité, les événements d'entrée utilisateur et les événements de rotation d'écran.
- La chronologie d'utilisation de la mémoire affiche les informations suivantes. Sélectionnez une partie de la chronologie pour filtrer une plage horaire spécifique.
- Un graphique empilé représentant la quantité de mémoire utilisée (indiquée sur l'axe vertical) par chaque catégorie (identifiée par la légende au-dessus du graphique).
- Une ligne en pointillé indiquant le nombre d'objets alloués (également sur l'axe vertical, à droite).
- Une icône pour chaque événement de récupération de mémoire.
- L'onglet Table affiche une liste de classes. Le nombre total correspond au nombre d'allocations à la fin de la période sélectionnée (Allocations moins Désallocations). Il peut donc être judicieux de déboguer en premier les classes qui présentent les valeurs Nombre total les plus élevées. Si vous souhaitez plutôt résoudre les problèmes liés aux classes en fonction des allocations maximales au cours de la période sélectionnée, classez-les par Allocations. De même, la taille restante correspond à la taille des allocations moins la taille des désallocations, en octets.
- Lorsque vous cliquez sur une classe dans la liste Table (Tableau), le volet Instance (Instance) s'ouvre avec une liste des objets associés, y compris la date à laquelle ils ont été alloués et désalloués, ainsi que leur taille superficielle.
L'onglet Visualisation affiche une vue agrégée de tous les objets de la pile d'appels au cours de la période sélectionnée. Il indique essentiellement la quantité totale de mémoire utilisée par la pile d'appels avec les instances affichées. La première ligne indique le nom du thread. Par défaut, les objets sont empilés de gauche à droite en fonction de la taille d'allocation. Utilisez le menu déroulant pour modifier l'ordre.
Utilisez le menu déroulant "Tas" pour filtrer certains tas. En plus des filtres disponibles lorsque vous capturez un vidage du tas de mémoire, vous pouvez filtrer les classes dans le tas de mémoire JNI, qui indique où les références JNI (Java Native Interface) sont allouées et libérées.
Utilisez le menu déroulant "Disposition" pour choisir comment organiser les allocations. En plus des dispositions disponibles lorsque vous capturez un vidage du tas, vous pouvez organiser les données par pile d'appels.
Méthode de comptabilisation de la mémoire
Les chiffres affichés en haut sont basés sur toutes les pages de mémoire privées réservées par votre application et connues du système Android. Ce décompte n'inclut pas les pages partagées avec le système ou avec d'autres applications. Les catégories de mémoire mesurées sont les suivantes :
- Java : la mémoire allouée aux objets issus du code Java ou Kotlin.
Native : la mémoire allouée aux objets issus du code C ou C++.
Votre application peut occuper de la mémoire native même si vous n'utilisez pas de C++, car le framework Android l'utilise pour traiter automatiquement différentes tâches en votre nom (notamment pour gérer les images et autres éléments graphiques, même si votre code est écrit en Java ou en Kotlin).
Graphique : la mémoire allouée aux files d'attente de tampon des éléments graphiques afin d'afficher des pixels à l'écran, y compris les surfaces et les textures GL, entre autres. Notez qu'il s'agit ici de mémoire partagée avec le processeur et non de mémoire GPU dédiée.
Pile : mémoire utilisée par les piles natives et Java dans votre application. Elle dépend généralement du nombre de threads exécutés par votre application.
Code : la mémoire utilisée pour le code et les ressources de votre application (bytecode DEX, code DEX optimisé ou compilé, .les bibliothèques
so
et les polices.Autres : mémoire utilisée par votre application, que le système ne sait pas comment catégoriser.
Alloué : nombre d'objets Java/Kotlin alloués par votre application. Les objets alloués en C ou C++ ne sont pas comptabilisés.
Inspecter l'enregistrement de l'allocation
Pour inspecter l'enregistrement d'allocation, procédez comme suit :
- Parcourez la liste des classes dans l'onglet Tableau pour trouver les objets ayant des valeurs Allocations ou Nombre total inhabituellement élevées (selon ce que vous optimisez) et susceptibles d'indiquer une fuite.
- Dans le volet Vue des instances, cliquez sur une instance. L'onglet Champs ou Pile d'appel d'allocation s'ouvre, selon ce qui s'applique à cette instance. Utilisez les informations des onglets Champs ou Pile d'appel d'allocation pour déterminer si les instances sont réellement nécessaires ou s'il s'agit de doublons inutiles.
Effectuez un clic droit sur une entrée de la liste pour accéder au code source correspondant.
Afficher les références JNI globales
Java Native Interface (JNI) est un framework qui permet au code Java et au code natif de s'appeler mutuellement. Les références JNI étant gérées manuellement par le code natif, il est possible que des problèmes tels que les suivants se produisent :
- Les objets Java utilisés par le code natif sont conservés pendant trop longtemps.
- Certains objets du tas de mémoire Java peuvent devenir inaccessibles si une référence JNI est abandonnée sans être explicitement supprimée.
- La limite de références JNI globales est atteinte.
Pour résoudre ces problèmes, sélectionnez Afficher le tas de mémoire JNI dans le profileur afin de parcourir toutes les références JNI globales et de les filtrer par types Java et piles d'appels natives. Effectuez un clic droit sur un champ d'instance dans l'onglet Champs, puis sélectionnez Accéder à l'instance pour afficher la pile d'appel d'allocation correspondante.
L'onglet Pile d'appel de l'allocation indique où les références JNI sont allouées et libérées dans votre code.
Pour plus d'informations sur JNI, consultez les conseils sur JNI.