Le Memory Profiler est un composant de l’Android Profiler qui vous aide à identifier les fuites de mémoire et le barattage de la mémoire qui peuvent conduire à des bégaiements,des gels et même des crashs d’app. Il affiche un graphique en temps réel de l’utilisation de la mémoire de votre application et vous permet de capturer un vidage du tas, de forcer les collectes de déchets et de suivre les allocations de mémoire.
Pour ouvrir le Memory Profiler, procédez comme suit :
- Cliquez sur View > Tool Windows > Profiler (vous pouvez également cliquer sur Profile dans la barre d’outils).
- Sélectionnez le périphérique et le processus d’application que vous souhaitez profiler dans la barre d’outils AndroidProfiler. Si vous avez connecté un périphérique par USB mais qu’il n’est pas listé, assurez-vous que vous avez activé le débogage USB.
- Cliquez n’importe où dans la ligne de temps MEMOIRE pour ouvrir le profileur de mémoire.
Alternativement, vous pouvez inspecter la mémoire de votre app à partir de la ligne de commande avecdumpsys, et également voir les événements GC dans logcat.
Pourquoi vous devriez profiler la mémoire de votre app
Android fournit un environnement de mémoire géré – lorsqu’il détermine que votre app n’utilise plus certains objets, le garbage collectorlibère la mémoire inutilisée dans le tas. La manière dont Android procède pour trouver la mémoire inutilisée est constamment améliorée, mais à un moment donné, sur toutes les versions d’Android, le système doit brièvement mettre votre code en pause. La plupart du temps, ces pauses sont imperceptibles. Cependant, si votre application alloue de la mémoire plus rapidement 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 pourrait faire sauter des images à votre application et provoquer une lenteur visible.
Même si votre application ne présente pas de lenteur, si elle fuit de la mémoire, elle peut conserver cette mémoire même lorsqu’elle est en arrière-plan. Ce comportement peut ralentir les performances du reste du système en matière de mémoire en forçant des événements de collecte de déchets inutiles. Finalement, le système est obligé de tuer le processus de votre application pour récupérer la mémoire. Ensuite, lorsque l’utilisateur revient à votre application, elle doit redémarrer complètement.
Pour aider à prévenir ces problèmes, vous devriez utiliser le Memory Profiler pour faire ce qui suit :
- Recherchez des modèles d’allocation de mémoire indésirables dans la ligne de temps qui pourraient causer des problèmes de performance.
- Dump le tas Java pour voir quels objets utilisent la mémoire à tout moment. Plusieurs vidages de tas sur une période de temps prolongée peuvent aider à identifier les fuites de mémoire.
- Enregistrez les allocations de mémoire pendant une interaction normale et extrême de l’utilisateur pour identifier exactement où votre code alloue trop d’objets dans un court laps de temps ou alloue des objets qui deviennent des fuites.
Pour des informations sur les pratiques de programmation qui peuvent réduire l’utilisation de la mémoire de votre application, lisez Gérer la mémoire de votre application.
Présentation du Memory Profiler
Lorsque vous ouvrez le Memory Profiler pour la première fois, vous voyez une chronologie détaillée de l’utilisation de la mémoire de votre application et accédez à des outils pour forcer la collecte des déchets, capturer un heapdump et enregistrer les allocations de mémoire.
Figure 1. Le profileur de mémoire
Comme l’indique la figure 1, la vue par défaut du profileur de mémoire comprend les éléments suivants :
- Un bouton pour forcer un événement de garbage collection.
-
Un bouton pour capturer un heap dump.
Note : Un bouton pour enregistrer les allocations de mémoire apparaît à droite du bouton de vidage du tas uniquement lorsqu’il est connecté à un appareil exécutant Android 7.1 (niveau 25 de l’API) ou moins.
- Un menu déroulant pour spécifier la fréquence à laquelle le profileur capture les allocations de mémoire. La sélection de l’option appropriée peut vous aider à améliorer les performances de l’app pendant le profilage.
- Des boutons pour faire un zoom avant/arrière de la ligne de temps.
- Un bouton pour sauter en avant vers les données de mémoire en direct.
- La ligne de temps des événements, qui montre les états d’activité, les événements d’entrée utilisateur et les événements de rotation d’écran.
- La timeline d’utilisation de la mémoire, qui comprend les éléments suivants :
- Un graphique empilé de la quantité de mémoire utilisée par chaque catégorie de mémoire, comme indiqué par l’axe des y à gauche et la clé de couleur en haut.
- Une ligne pointillée indique le nombre d’objets alloués, comme indiqué par l’axe des y à droite.
- Une icône pour chaque événement de collecte de déchets.
Cependant, si vous utilisez un appareil fonctionnant sous Android 7.1 ou moins, toutes les données de profilage ne sont pas visibles par défaut. Si vous voyez un message indiquant que le profilage avancé est indisponible pour le processus sélectionné, vous devez activer le profilage avancé pour voir les éléments suivants :
- La chronologie des événements
- Le nombre d’objets alloués
- Les événements de collecte d’ordures
Sur Android 8.0 et plus, le profilage avancé est toujours activé pour les applications déboguables.
Comment la mémoire est comptée
Les chiffres que vous voyez en haut du profileur de mémoire (figure 2) sont basés sur toutes les pages de mémoire privées que votre application a engagées, selon le systèmeAndroid. Ce compte n’inclut pas les pages partagées avec le système ou d’autres apps.
Figure 2. La légende du décompte de la mémoire en haut du Memory Profiler
Les catégories du décompte de la mémoire sont les suivantes :
- Java : Mémoire provenant d’objets alloués à partir du code Java ou Kotlin.
-
Natif : Mémoire provenant d’objets alloués à partir de code C ou C++.
Même si vous n’utilisez pas C++ dans votre application, vous pourriez voir une partie de la mémoire native utilisée ici car le framework Android utilise la mémoire native pour gérer diverses tâches en votre nom, comme lors de la manipulation des actifs d’image et d’autres graphiques – même si le code que vous avez écrit est en Java ou en Kotlin.
-
Graphique : Mémoire utilisée pour les files d’attente de tampons graphiques pour afficher les pixels à l’écran, y compris les surfaces GL, les textures GL, et ainsi de suite. (Notez qu’il s’agit d’une mémoire partagée avec le CPU, et non d’une mémoire dédiée au GPU.)
-
Stack : La mémoire utilisée par les piles natives et Java dans votre application. Cela concerne généralement le nombre de threads que votre app exécute.
-
Code : La mémoire que votre app utilise pour le code et les ressources, tels que le bytecode dex, le code dex optimisé ou compilé, les bibliothèques .so et les polices.
-
Autres : La mémoire utilisée par votre application que le système ne sait pas comment catégoriser.
-
Allocated : Le nombre d’objets Java/Kotlin alloués par votre app. Cela ne compte pas les objets alloués en C ou C++.
Lorsque vous êtes connecté à un appareil fonctionnant sous Android 7.1 et inférieur, ce décompte d’allocation ne commence qu’au moment où le profileur de mémoire s’est connecté à votre app en cours d’exécution. Ainsi, tout objet alloué avant le début du profilage n’est pas comptabilisé. Cependant, Android 8.0 et plus inclut un outil de profilage sur l’appareil qui garde la trace de toutes les allocations, donc ce nombre représente toujours le nombre total d’objets Java en circulation dans votre application sur Android 8.0 et plus.
Lorsque l’on compare avec les comptes de mémoire de l’outil Android Monitor précédent, le nouveauMemory Profiler enregistre votre mémoire différemment, donc il pourrait sembler que votre utilisation de la mémoire est maintenant plus élevée. Le Memory Profiler surveille certaines catégories supplémentaires qui augmentent le total, mais si vous ne vous souciez que de la mémoire du tas Java, le nombre « Java » devrait être similaire à la valeur de l’outil précédent.Bien que le nombre Java ne corresponde probablement pas exactement à ce que vous avez vu dans AndroidMonitor, le nouveau nombre tient compte de toutes les pages de mémoire physique qui ont été allouées au tas Java de votre application depuis qu’elle a été bifurquée de Zygote. Cela fournit donc une représentation précise de la quantité de mémoire physique que votre application utilise réellement.
Voir les allocations de mémoire
Les allocations de mémoire vous montrent comment chaque objet Java et référence JNI dans votremémoire a été alloué. Plus précisément, le Memory Profiler peut vous montrer ce qui suit sur les allocations d’objets :
- Quels types d’objets ont été alloués et combien d’espace ils utilisent.
- La trace de pile de chaque allocation, y compris dans quel thread.
- Quand les objets ont été désalloués (uniquement lors de l’utilisation d’un appareil avec Android 8.0 ou supérieur).
Si votre appareil exécute Android 8.0 ou supérieur, vous pouvez visualiser vos allocations d’objets à tout moment comme suit : Faites glisser dans la ligne de temps pour sélectionner la région pour laquelle vous voulez voir les allocations (comme indiqué dans la vidéo 1). Il n’est pas nécessaire de commencer une session d’enregistrement, car Android 8.0 et supérieur comprend un outil de profilage sur périphérique qui suit constamment les allocations de votre application.
Vidéo 1. Avec Android 8.0 et supérieur, sélectionnez une zone de ligne de temps existante pour afficher les allocations d’objets
Si votre appareil exécute Android 7.1 ou inférieur, cliquez sur Enregistrer les allocations de mémoire dans la barre d’outils Memory Profiler. Pendant l’enregistrement, leMemory Profiler suit toutes les allocations qui se produisent dans votre application. Lorsque vous avez terminé, cliquez sur Arrêter l’enregistrement(le même bouton ; voir la vidéo 2) pour afficher les allocations.
Vidéo 2. Avec Android 7.1 et inférieur, vous deveztexplicitement enregistrer les allocations de mémoire
Après avoir sélectionné une région de la timeline (ou lorsque vous terminez une session d’enregistrement avec un appareil fonctionnant sous Android 7.1 ou inférieur), la liste des objets alloués apparaît sous la ligne de temps, regroupés par nom de classe et triés par leur compte de tas.
Pour inspecter l’enregistrement de l’allocation, suivez ces étapes :
- Parcourez la liste pour trouver les objets qui ont des comptes de tas inhabituellement élevés etqui pourraient faire l’objet d’une fuite. Pour aider à trouver les classes connues, cliquez sur l’en-tête de la colonne Nom de la classe pour effectuer un tri alphabétique. Cliquez ensuite sur le nom d’une classe. Le volet Vue des instances apparaît sur la droite, montrant chaque instance de cette classe, comme le montre la figure 3.
- Alternativement, vous pouvez localiser rapidement des objets en cliquant sur Filtre,ou en appuyant sur Control+F (Command+F sur Mac), et en entrant un nom de classe ou de packagen dans le champ de recherche. Vous pouvez également effectuer une recherche par nom de méthode si vous sélectionnezArrangement par pile d’appels dans le menu déroulant. Si vous souhaitez utiliser des expressions régulières, cochez la case en regard de Regex. Cochez la case à côté deMatch case si votre requête de recherche est sensible à la casse.
- Dans le volet Vue des instances, cliquez sur une instance. L’onglet Call Stackapparaît ci-dessous, montrant où cette instance a été allouée et dans quel thread.
- Dans l’onglet Call Stack, cliquez avec le bouton droit de la souris sur n’importe quelle ligne et choisissezJump to Source pour ouvrir ce code dans l’éditeur.
Figure 3. Les détails sur chaque objet allouéapparaissent dans la vue d’instance à droite
Vous pouvez utiliser les deux menus au-dessus de la liste des objets alloués pour choisir le tas à inspecter et la façon d’organiser les données.
Dans le menu de gauche, choisissez le tas à inspecter:
- tas par défaut : Lorsqu’aucun tas n’est spécifié par le système.
- tas d’image : L’image de démarrage du système, contenant les classes qui sontpréchargées pendant le démarrage. Les allocations ici sont garanties de ne jamais bouger ou partir.
- tas zygote : Le tas de copie sur écriture à partir duquel un processus d’application est bifurqué dans le système Android.
- tas d’application : Le tas primaire sur lequel votre app alloue de la mémoire.
- JNI heap : Le tas qui montre où les références de l’interface native Java (JNI) sont allouées et libérées.
Dans le menu de droite, choisissez comment organiser les allocations :
- Organiser par classe : Regroupe toutes les allocations en fonction du nom de la classe. Il s’agit de la valeur par défaut.
- Classer par paquet : Regroupe toutes les allocations en fonction du nom du paquet.
- Arrangement par pile d’appels : Regroupe toutes les allocations dans leur pile d’appels correspondante.
Améliorer les performances de l’application lors du profilage
Pour améliorer les performances de l’application lors du profilage, le profileur de mémoire échantillonne périodiquement les allocations de mémoire par défaut. Lorsque vous effectuez des tests sur des appareils exécutant le niveau 26 de l’API ou plus, vous pouvez modifier ce comportement en utilisant la liste déroulante Suivi des allocations. Les options disponibles sont les suivantes :
- Complet : capture toutes les allocations d’objets en mémoire. Il s’agit du comportement par défaut dans Android Studio 3.2 et antérieur. Si vous avez une application qui alloue beaucoup d’objets, vous pouvez observer des ralentissements visibles avec votre application lors du profilage.
- Échantillonné : Échantillonne les allocations d’objets en mémoire à intervalles réguliers. C’est l’option par défaut et elle a moins d’impact sur les performances de l’app lors du profilage. Les apps qui allouent beaucoup d’objets sur une courte période de temps peuvent quand même présenter des ralentissements visibles.
- Off : Arrête de suivre l’allocation de mémoire de votre app.
Voir les références JNI globales
L’interface native Java (JNI) est un cadre qui permet au code Java et au code natif de s’appeler mutuellement.
Les références JNI sont gérées manuellement par le code natif, il est donc possible que les objetsJava utilisés par le code natif soient maintenus en vie trop longtemps. Certains objets du tas Java peuvent devenir inaccessibles si une référence JNI est abandonnée sans avoir été préalablement explicitement supprimée. De même, il est possible d’épuiser la limite de référence JNI globale.
Pour résoudre ces problèmes, utilisez la vue du tas JNI dans le Memory Profiler pour parcourir toutes les références JNI globales et les filtrer par types Java et Callstacks natifs. Avec ces informations, vous pouvez trouver quand et où les références JNI globales sont créées et supprimées.
Alors que votre application est en cours d’exécution, sélectionnez une partie de la timeline que vous souhaitez inspecter et sélectionnez JNI heap dans le menu déroulant au-dessus de la liste des classes.Vous pouvez ensuite inspecter les objets dans le tas comme vous le feriez normalement et double-cliquer sur les objets dans l’onglet Pile d’appels d’allocation pour voir où les références JNI sont allouées et libérées dans votre code, comme indiqué sur la figure 4.
Figure 4. Affichage des références JNI globales
Pour inspecter les allocations de mémoire pour le code JNI de votre application, vous devez déployer votre application sur un appareil fonctionnant sous Android 8.0 ou supérieur.
Pour plus d’informations sur JNI, consultez les conseils JNI.
Profileur de mémoire native
Le profileur de mémoire d’Android Studio comprend un profileur de mémoire native pour les applications déployées sur des appareils physiques exécutant Android 10 ; la prise en charge des appareils Android 11 est actuellement disponible dans la version preview d’Android Studio 4.2.
Le profileur de mémoire native suit les allocations/désallocations d’objets dans le code natif pendant une période spécifique et fournit les informations suivantes :
- Allocations : Un compte des objets alloués via
malloc()
ou l’opérateurnew
pendant la période de temps sélectionnée. - Déallocations : Un compte des objets désalloués via
free()
ou l’opérateurdelete
pendant la période sélectionnée. - Allocations Size : La taille agrégée en octets de toutes les allocations pendant la période sélectionnée.
- Taille des désallocations : La taille agrégée en octets de toute la mémoire libérée pendant la période sélectionnée.
- Total Count : La valeur de la colonne Allocations moins la valeur de la colonne Déallocations.
- Taille restante : La valeur de la colonne Taille des allocations moins la valeur de la colonne Taille des désallocations.
Pour lancer un enregistrement, cliquez sur Enregistrer les allocations natives en haut de la fenêtreMemory Profiler:
Quand vous êtes prêt à terminer l’enregistrement, cliquez sur Arrêter l’enregistrement.
Par défaut, le Native Memory Profiler utilise une taille d’échantillon de 32 octets : Chaque fois que 32 octets de mémoire sont alloués, un instantané de la mémoire est pris. Une taille d’échantillon plus petite entraîne des instantanés plus fréquents, produisant des données plus précises sur l’utilisation de la mémoire. Une taille d’échantillon plus grande donne des données moins précises, mais elle consommera moins de ressources sur votre système et améliorera les performances pendant l’enregistrement.
Pour modifier la taille d’échantillon du profileur de mémoire native :
- Sélectionnez Exécuter > Modifier les configurations.
- Sélectionnez votre module d’app dans le volet de gauche.
- Cliquez sur l’onglet Profilage et saisissez la taille de l’échantillon dans le champ intituléIntervalle d’échantillonnage de la mémoire native (octets).
- Construisez et exécutez à nouveau votre app.
Capturer un vidage de tas
Un vidage de tas montre quels objets de votre app utilisent la mémoire au moment où vouscapturez le vidage de tas. En particulier après une session utilisateur prolongée, un vidage du tas peut aider à identifier les fuites de mémoire en montrant les objets encore en mémoire qui, selon vous, ne devraient plus être là.
Après avoir capturé un vidage du tas, vous pouvez voir ce qui suit :
- Quels types d’objets votre app a alloués, et combien de chacun.
- Combien de mémoire chaque objet utilise.
- Où les références à chaque objet sont maintenues dans votre code.
- La pile d’appel pour l’endroit où un objet a été alloué. (Les piles d’appels sont actuellement disponibles avec un vidage du tas uniquement avec Android 7.1 et inférieur lorsque vous capturez le vidage du tas tout en enregistrant les allocations.)
Pour capturer un vidage du tas, cliquez sur Dump Java heap dans la barre d’outils Memory Profiler.Pendant le vidage du tas, la quantité de mémoire Java peut augmenter temporairement.C’est normal car le vidage du tas se produit dans le même processus que votre applicationet nécessite un peu de mémoire pour collecter les données.
Le vidage du tas apparaît sous la chronologie de la mémoire, montrant tous les types de classe dans le tas, comme indiqué dans la figure 5.
Figure 5. Visualisation du vidage du tas
Si vous avez besoin d’être plus précis sur le moment où le vidage est créé, vous pouvez créer un vidage du tas au point critique du code de votre application en appelantdumpHprofData()
.
Dans la liste des classes, vous pouvez voir les informations suivantes :
- Allocations : Nombre d’allocations dans le tas.
-
Taille native : Quantité totale de mémoire native utilisée par ce type d’objet(en octets). Cette colonne n’est visible que pour Android 7.0 et plus.
Vous verrez ici de la mémoire pour certains objets alloués en Java car Android utilise la mémoire native pour certaines classes du framework, comme
Bitmap
. -
Shallow Size : Taille totale de la mémoire Java utilisée par ce type d’objet (en octets).
-
Taille retenue : Taille totale de la mémoire retenue en raison de toutes les instancesde cette classe (en octets).
Vous pouvez utiliser les deux menus au-dessus de la liste des objets alloués pour choisir les vidages de tas à inspecter et la façon d’organiser les données.
Dans le menu de gauche, choisissez le tas à inspecter :
- tas par défaut : Lorsqu’aucun tas n’est spécifié par le système.
- tas d’application : Le tas primaire sur lequel votre application alloue de la mémoire.
- tas d’image : L’image de démarrage du système, contenant les classes qui sontpréchargées au moment du démarrage. Les allocations ici sont garanties de ne jamais bouger ou partir.
- zygote heap : Le tas de copie sur écriture à partir duquel un processus d’application est bifurqué dans le système Android.
Dans le menu de droite, choisissez comment organiser les allocations :
- Organiser par classe : Regroupe toutes les allocations en fonction du nom de la classe. Il s’agit de la valeur par défaut.
- Classer par paquet : Regroupe toutes les allocations en fonction du nom du paquet.
- Arrangement par pile d’appels : Regroupe toutes les allocations dans leur pile d’appel correspondante. Cette option ne fonctionne que si vous capturez le vidage du tas pendant l’enregistrement des allocations. Même ainsi, il est probable qu’il y ait des objets dans le tas qui ont été alloués avant que vous ne commenciez à enregistrer, donc ces allocations apparaissent en premier,simplement listées par nom de classe.
La liste est triée par la colonne Taille retenue par défaut. Pour trier par les valeurs d’une colonne différente, cliquez sur l’en-tête de la colonne.
Cliquez sur un nom de classe pour ouvrir la fenêtre Vue des instances sur la droite(illustrée à la figure 6). Chaque instance répertoriée comprend les éléments suivants :
- Profondeur : Le nombre le plus court de sauts de toute racine GC à l’instance sélectionnée.
- Taille native : Taille de cette instance en mémoire native.Cette colonne n’est visible que pour Android 7.0 et plus.
- Taille superficielle : Taille de cette instance dans la mémoire Java.
- Taille retenue : Taille de la mémoire que cette instance domine (selon l’arbre du dominateur).
Figure 6. La durée nécessaire pour capturer un heapdump est indiquée dans la ligne de temps
Pour inspecter votre heap, suivez ces étapes:
- Parcourez la liste pour trouver les objets qui ont des comptes de heap inhabituellement grands etqui pourraient avoir des fuites. Pour aider à trouver les classes connues, cliquez sur l’en-tête de la colonne Nom de la classe pour effectuer un tri alphabétique. Cliquez ensuite sur le nom d’une classe. Le volet Vue des instances apparaît sur la droite, montrant chaque instance de cette classe, comme le montre la figure 6.
- Alternativement, vous pouvez localiser rapidement des objets en cliquant sur Filtre,ou en appuyant sur Control+F (Command+F sur Mac), et en entrant un nom de classe ou de packagen dans le champ de recherche. Vous pouvez également effectuer une recherche par nom de méthode si vous sélectionnezArrangement par pile d’appels dans le menu déroulant. Si vous souhaitez utiliser des expressions régulières, cochez la case en regard de Regex. Cochez la case à côté deMatch case si votre requête de recherche est sensible à la casse.
- Dans le volet Vue des instances, cliquez sur une instance. La table des références apparaît ci-dessous, montrant chaque référence à cet objet.
Ou, cliquez sur la flèche à côté du nom de l’instance pour afficher tous ses champs, puis cliquez sur un nom de champ pour afficher toutes ses références. Si vous souhaitez afficher les détails de l’instance pour un champ, cliquez avec le bouton droit de la souris sur le champ et sélectionnez Aller à l’instance.
- Dans l’onglet Références, si vous identifiez une référence qui pourrait perdre de la mémoire, cliquez avec le bouton droit de la souris et sélectionnez Aller à l’instance. Cela sélectionne l’instance correspondante dans le vidage du tas, en vous montrant ses propres données d’instance.
Dans votre vidage du tas, recherchez les fuites de mémoire causées par l’un des éléments suivants :
- Références de longue durée à
Activity
,Context
,View
,Drawable
et autres objets qui pourraient contenir une référence au conteneurActivity
ouContext
. - Les classes internes non statiques, telles qu’une
Runnable
, qui peuvent contenir une instance deActivity
. - Les caches qui conservent les objets plus longtemps que nécessaire.
Enregistrer un vidage de tas en tant que fichier HPROF
Après avoir capturé un vidage de tas, les données sont visualisables dans le profileur de mémoire uniquement pendant l’exécution du profileur. Lorsque vous quittez la session de profilage, vous perdez le dump du tas. Donc, si vous voulez le sauvegarder pour le revoir plus tard, exportez le vidage du tas dans un fichier HPROF. Dans Android Studio 3.1 et versions inférieures, le bouton Exporter la capture vers le fichier se trouve sur le côté gauche de la barre d’outils, sous la barre temporelle ; dans Android Studio 3.2 et versions supérieures, un bouton Exporter le vidage du tas se trouve à droite de chaque entrée de vidage du tas dans le volet Sessions. Dans la boîte de dialogue Exporter sous qui apparaît, enregistrez le fichier avec l’extension de nom de fichier .hprof
.
Pour utiliser un autre analyseur HPROF commejhat,vous devez convertir le fichier HPROF du format Android au format HPROF Java SE.Vous pouvez le faire avec l’outil hprof-conv
fourni dans le répertoireandroid_sdk/platform-tools/
. Exécutez la commande hprof-conv
avec deux arguments : le fichier HPROF original et l’emplacement où écrire le fichier HPROF converti. Par exemple :
hprof-conv heap-original.hprof heap-converted.hprof
Importer un fichier de vidage de tas
Pour importer un fichier HPROF (.hprof
), cliquez sur Démarrer une nouvelle session de profilage dans le voletSessions, sélectionnez Charger à partir d’un fichier, puis choisissez le fichier dans le navigateur de fichiers.
Vous pouvez également importer un fichier HPROF en le faisant glisser du navigateur de fichiers vers une fenêtre d’éditeur.
Détection de fuites dans le Memory Profiler
Lors de l’analyse d’un vidage de tas dans le Memory Profiler, vous pouvez filtrer les données de profilage qui, selon Android Studio, pourraient indiquer des fuites de mémoire pour Activity
etFragment
instances de votre application.
Les types de données que le filtre montre incluent les suivantes :
-
Activity
instances qui ont été détruites mais qui sont toujours référencées. -
Fragment
instances qui n’ont pas deFragmentManager
valide mais qui sont toujours référencées.
Dans certaines situations, comme les suivantes, le filtre peut donner de faux positifs :
- Un
Fragment
est créé mais n’a pas encore été utilisé. - Un
Fragment
est mis en cache mais ne fait pas partie d’unFragmentTransaction
.
Pour utiliser cette fonctionnalité, capturez d’abord un vidage de tas ou importez un fichier de vidage de tasdans Android Studio. Pour afficher les fragments et les activités qui peut-être fuient la mémoire, cochez la case Fuites d’activité/fragment dans le volet heapdump du profileur de mémoire, comme indiqué sur la figure 7.
Figure 7. Filtrage d’un dump de tas pour les fuites de mémoire.
Techniques pour profiler votre mémoire
Tout en utilisant le Memory Profiler, vous devriez stresser votre code d’app et essayer de forcer les fuites de mémoire. Une façon de provoquer des fuites de mémoire dans votre application est de la laisser tourner pendant un certain temps avant d’inspecter le tas. Les fuites peuvent s’accumuler jusqu’au sommet des allocations dans le tas. Cependant, plus la fuite est petite, plus vous devez faire tourner l’application longtemps pour la voir.
Vous pouvez également déclencher une fuite de mémoire de l’une des manières suivantes :
- Rottez l’appareil du portrait au paysage et inversement plusieurs fois alors qu’il est dans différents états d’activité. Faire pivoter l’appareil peut souvent causer une fuite d’un objet
Activity
,Context
, ouView
parce que le systèmerecrée leActivity
et si votreapp détient une référence à l’un de ces objets quelque part ailleurs, le système ne peut pas le vider. - Balancez-vous entre votre application et une autre application alors qu’elles sont dans des états d’activité différents (naviguez jusqu’à l’écran d’accueil, puis revenez à votre application).
Tip : Vous pouvez également effectuer les étapes ci-dessus en utilisant themonkeyrunner testframework.