Dans Android Studio, la fenêtre Logcat affiche des messages système tels que les événements de récupération de mémoire et les messages que vous avez ajoutés à votre application avec la classe Log
. Logcat affiche les messages en temps réel et conserve un historique pour que vous puissiez consulter les messages plus anciens.
Pour n'afficher que les informations qui vous intéressent, vous pouvez créer des filtres, modifier le volume d'informations affichées dans les messages, définir les niveaux de priorité, afficher uniquement les messages générés par le code de l'application et effectuer une recherche dans le journal. Par défaut, Logcat n'affiche que la sortie du journal associée à la dernière application exécutée.
Lorsqu'une application génère une exception, Logcat affiche un message suivi de la trace de la pile associée contenant les liens vers la ligne de code.
La fenêtre "Run" (Exécuter) affiche les messages de journal de l'application en cours d'exécution. Vous pouvez configurer l'affichage de la sortie Logcat, mais pas cette fenêtre.
Afficher les journaux de votre application
Pour afficher les messages de journal d'une application :
- Compilez et exécutez votre application sur un appareil.
- Cliquez sur View > Tool Windows > Logcat (Afficher > Fenêtres d'outils > Logcat) ou sur Logcat
dans la barre des fenêtres d'outils.
La fenêtre Logcat affiche les messages de journal de l'application sélectionnée dans le menu en haut de la fenêtre, comme l'illustre la figure 1.
Par défaut, Logcat n'affiche que les messages de journal de l'application exécutée sur l'appareil. Pour modifier cette valeur par défaut, découvrez comment filtrer les messages Logcat.
La barre d'outils Logcat comporte les boutons suivants :
- Clear logcat (Effacer Logcat)
: cliquez pour effacer le journal visible.
- Scroll to the end (Faire défiler la page jusqu'à la fin)
: cliquez sur cette option pour aller au bas du journal et voir les derniers messages. Si vous cliquez ensuite sur une ligne du journal, l'affichage interrompt le défilement au point atteint.
- Up the stack trace (Vers le haut de la trace de la pile)
et Down the stack trace (Vers le bas de la trace de la pile)
: cliquez sur ces boutons pour parcourir les traces de la pile vers le haut ou vers le bas dans le journal, en sélectionnant le nom de fichier précédent ou suivant qui apparaît dans les exceptions imprimées. Ce comportement est le même que lorsque vous cliquez sur un nom de fichier dans le journal.
- Use soft wraps (Utiliser des retours à la ligne automatiques)
: cliquez sur cette option pour activer le retour à la ligne automatique et empêcher le défilement horizontal. Notez toutefois que les chaînes insécables nécessiteront toujours le défilement horizontal.
- Print (Imprimer)
: cliquez sur ce bouton pour imprimer les messages Logcat. Après avoir sélectionné vos préférences d'impression dans la boîte de dialogue qui s'affiche, vous pouvez également choisir d'enregistrer les messages au format PDF.
- Restart (Redémarrer)
: cliquez sur ce bouton pour effacer le journal et redémarrer Logcat. Contrairement au bouton Clear Logcat (Effacer Logcat), cette option récupère et affiche les messages de journal précédents. Il est donc particulièrement utile si Logcat ne répond plus et que vous ne souhaitez pas perdre vos messages de journal.
- Logcat header (En-tête Logcat)
: cliquez sur ce bouton pour ouvrir la boîte de dialogue Configure Logcat Header (Configurer l'en-tête Logcat), dans laquelle vous pouvez personnaliser l'apparence de chaque message Logcat. Vous pouvez par exemple choisir d'afficher ou non la date et l'heure.
- Screen capture (Capture d'écran)
: cliquez sur ce bouton pour faire une capture d'écran.
- Screen record (Enregistrement de l'écran)
: cliquez sur ce bouton pour enregistrer une vidéo de l'appareil de trois minutes maximum.
Écrire des messages de journal
La classe Log
vous permet de créer des messages de journal qui apparaîtront dans Logcat. Chaque message de journal Android est associé à une balise et à une priorité. La balise d'un message de journal système est une chaîne courte indiquant le composant système d'où provient le message.
Utilisez les méthodes de journalisation suivantes, classées de la priorité la plus haute à la priorité la plus basse :
- Error (Erreur) :
Log.e(String, String)
- Warning (Avertissement) :
Log.w(String, String)
- Information :
Log.i(String, String)
- Debug (Débogage) :
Log.d(String, String)
- Verbose (Détail) :
Log.v(String, String)
Une balise définie par l'utilisateur peut être n'importe quelle chaîne que vous trouvez utile, comme le nom de la classe actuelle. Cette balise est définie dans un appel de méthode Log
, par exemple :
Kotlin
Log.d(tag, message)
Java
Log.d(tag, message);
Consultez la description de la classe Log
pour obtenir une liste plus complète des options.
Ne compilez jamais de journaux détaillés dans votre application, sauf pendant le développement. Les journaux de débogage sont compilés, mais supprimés lors de l'exécution. Les journaux d'erreurs, d'avertissement et d'information sont toujours conservés.
Pour chaque méthode de journalisation, le premier paramètre doit être une balise unique, et le deuxième le message. La balise d'un message de journal système est une chaîne courte indiquant le composant système d'où provient le message. Une balise définie par l'utilisateur peut être n'importe quelle chaîne utile, telle que le nom de la classe actuelle.
Il est recommandé de déclarer une constante TAG
dans votre classe à utiliser dans le premier paramètre. Par exemple, vous pouvez créer un message de journal d'information comme suit :
Kotlin
private const val TAG = "MyActivity" ... Log.i(TAG, "MyClass.getView() — get item number $position")
Java
private static final String TAG = "MyActivity"; ... Log.i(TAG, "MyClass.getView() — get item number " + position);
Remarque : Les noms de balises de plus de 23 caractères sont tronqués dans la sortie Logcat.
Format d'un message Logcat
Voici le format d'un message de journal :
date time PID-TID/package priority/tag: message
PID correspond à "process identifier", qui signifie "identifiant de processus", et TID à "thread identifier", qui signifie "identifiant de thread". Ils peuvent être identiques s'il n'y a qu'un seul thread.
Par exemple, le message de journal suivant a la priorité V
et la balise AuthZen
:
12-10 13:02:50.071 1901-4229/com.google.android.gms V/AuthZen: Handling delegate intent.
Définir le niveau de journalisation
Vous pouvez définir le niveau de journalisation pour contrôler si Logcat doit afficher tous les messages ou uniquement ceux qui indiquent les conditions les plus sérieuses.
Logcat continue de collecter tous les messages, quel que soit le niveau de journalisation. Ce paramètre détermine simplement ce que Logcat affiche.
Dans le menu Log level (Niveau de journalisation), sélectionnez l'une des valeurs suivantes :
- Verbose (Détail) : affiche tous les messages de journal (par défaut).
- Debug (Débogage) : affiche les messages de journal de débogage qui ne sont utiles qu'au cours du développement, ainsi que les messages de niveaux suivants de cette liste.
- Info : affiche les messages de journal attendus pour un usage régulier, ainsi que les messages de niveaux suivants de cette liste.
- Warn (Avertissement) : affiche les problèmes potentiels qui ne sont pas encore des erreurs, ainsi que les messages de niveaux suivants de cette liste.
- Error (Erreur) : affiche les problèmes ayant provoqué des erreurs, ainsi que les messages du niveau suivant de cette liste.
- Assert (Assertion) : affiche les problèmes que le développeur ne devrait jamais rencontrer.
Rechercher des messages Logcat
Pour rechercher les messages affichés dans Logcat :
- Sélectionnez Regex (Expression régulière) si vous souhaitez utiliser un modèle de recherche d'expression régulière (facultatif).
- Indiquez une séquence de caractères dans le champ de recherche
.
L'affichage de la sortie Logcat s'ajuste en conséquence.
- Appuyez sur Entrée pour stocker la chaîne de recherche dans le menu au cours de cette session.
- Pour répéter une recherche, sélectionnez-la dans le menu de recherche. Sélectionnez ou désélectionnez Regex (Expression régulière) si nécessaire.
Filtrer les messages Logcat
Pour réduire la sortie du journal à un niveau gérable, vous pouvez la restreindre à l'aide d'un filtre.
Remarque : Le filtre s'applique à l'ensemble de votre historique Logcat, et pas seulement aux messages actuellement affichés dans Logcat. Assurez-vous que vos autres options d'affichage sont définies correctement afin de voir la sortie filtrée que vous souhaitez examiner.
Pour définir et appliquer un filtre :
- Dans le menu "Filter" (Filtre), sélectionnez une option de filtre :
- Show only selected application (Afficher uniquement l'application sélectionnée) : n'affiche que les messages générés par le code de l'application (par défaut). Logcat filtre les messages de journal en utilisant le PID de l'application active.
- No Filters (Aucun filtre) : n'applique aucun filtre. Logcat affiche tous les messages de journal de l'appareil, quel que soit le processus sélectionné.
- Edit Filter Configuration (Modifier la configuration du filtre) : crée ou modifie un filtre personnalisé. Par exemple, vous pouvez créer un filtre pour afficher les messages de journal de deux applications en même temps.
Après avoir défini des filtres, vous pouvez également les sélectionner dans le menu. Pour les enlever du menu, supprimez-les.
- Si vous avez sélectionné Edit Filter Configuration (Modifier la configuration du filtre), créez ou modifiez un filtre :
- Indiquez les paramètres de filtre dans la boîte de dialogue Create New Logcat Filter (Créer un filtre Logcat) :
- Filter Name (Nom du filtre) : saisissez le nom d'un filtre que vous souhaitez définir ou sélectionnez un filtre existant dans le volet de gauche pour le modifier. Ce nom ne peut contenir que des caractères minuscules, des traits de soulignement et des chiffres.
- Log Tag (Balise de journal) : vous pouvez spécifier une balise (facultatif).
- Log Message (Message de journal) : vous pouvez indiquer le texte du message de journal (facultatif).
- Package Name (Nom du package) : vous pouvez indiquer un nom de package (facultatif).
- PID : vous pouvez indiquer un identifiant de processus (facultatif).
- Log Level (Niveau de journalisation) : vous pouvez sélectionner un niveau de journalisation (facultatif).
- Regex (Expression régulière) : sélectionnez cette option si vous souhaitez utiliser une expression régulière pour ce paramètre.
-
Cliquez sur le signe + pour ajouter la définition du filtre au volet de gauche.
Pour supprimer un filtre, sélectionnez-le dans le volet de gauche, puis cliquez sur -.
- Lorsque vous avez terminé, cliquez sur OK.
- Indiquez les paramètres de filtre dans la boîte de dialogue Create New Logcat Filter (Créer un filtre Logcat) :
Si vous ne voyez pas les messages de journal souhaités, sélectionnez No filters (Aucun filtre) et recherchez des messages de journal spécifiques.
Lire les messages de récupération de mémoire
Lorsqu'un événement de récupération de mémoire a lieu, des informations sont parfois envoyées à Logcat.
Pour en savoir plus sur la mémoire de votre application, utilisez le Profileur de mémoire.
Messages de journal Dalvik
Dans Dalvik (à l'inverse d'ART), chaque récupération de mémoire imprime les informations suivantes dans Logcat :
D/dalvikvm(PID): GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time
Exemple :
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
Pendant que les messages de journal s'accumulent, recherchez des augmentations dans les statistiques des tas de mémoire. Si cette valeur continue d'augmenter, il peut s'agir d'une fuite de mémoire.
Les termes suivants sont employés dans les messages de journal Dalvik :
- Motif de la récupération de mémoire
-
Motif de la récupération de mémoire et type de récupération dont il s'agit. Voici les différents motifs possibles :
GC_CONCURRENT
- Récupération de mémoire simultanée qui libère de la mémoire au fur et à mesure que le tas de mémoire commence à se remplir.
GC_FOR_MALLOC
- Récupération de mémoire due au fait que votre application a tenté d'allouer de la mémoire alors que le tas de mémoire était déjà rempli. Le système a donc dû arrêter votre application pour récupérer de la mémoire.
GC_HPROF_DUMP_HEAP
- Récupération de mémoire qui se produit lorsque vous demandez la création d'un fichier HPROF pour analyser le tas de mémoire.
GC_EXPLICIT
- Motif de récupération de mémoire explicite, par exemple lorsque vous appelez
gc()
. Toutefois, évitez d'appeler cette méthode. Laissez plutôt la récupération de mémoire s'exécuter en cas de besoin. GC_EXTERNAL_ALLOC
- Récupération de mémoire pour la mémoire allouée en externe (telles que les données de pixels stockées dans la mémoire native ou les tampons d'octets NIO). Ce comportement ne se produit qu'au niveau d'API 10 et inférieur. Les versions plus récentes allouent tout ce qui se trouve dans le tas de mémoire Dalvik.
- Quantité libérée
- Quantité de mémoire récupérée grâce à cette récupération de mémoire.
- Statistiques du tas de mémoire
- Pourcentage libre du tas de mémoire et (nombre d'objets actifs)/(taille totale du tas de mémoire).
- Statistiques de mémoire externe
- Mémoire allouée en externe à partir du niveau d'API 10 (quantité de mémoire allouée)/(limite au-delà de laquelle la récupération se produit).
- Pause
- Les segments de mémoire plus volumineux ont des temps de pause plus longs. Les temps de pause simultanés indiquent deux pauses : une au début de la récupération et l'autre à la fin.
Messages de journal ART
Contrairement à Dalvik, ART ne consigne pas les messages de journal des récupérations de mémoire qui n'ont pas été explicitement demandées. Les informations de récupération de mémoire ne sont imprimées que lorsque la récupération de mémoire est explicite, que sa pause dépasse 5 ms ou que sa durée dépasse 100 ms. Si l'application n'est pas en état de pause perceptible (par exemple, lorsque l'application est en arrière-plan et que l'utilisateur ne peut pas la voir), aucune information de récupération de mémoire n'est imprimée, sauf pour les récupérations de mémoire explicites.
ART comprend les informations suivantes dans ses messages de journal de récupération de mémoire :
I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects, Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s)
Exemple :
I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms
Les termes suivants sont employés dans les messages de journal ART :
- Motif de la récupération de mémoire
-
Motif de la récupération de mémoire et type de récupération dont il s'agit. Voici les différents motifs possibles :
Concurrent
- Récupération de mémoire simultanée qui n'interrompt pas les threads de l'application. Cette récupération de mémoire s'exécute dans un thread en arrière-plan et n'empêche pas les allocations.
Alloc
- La récupération de mémoire a été lancée, car votre application a tenté d'allouer de la mémoire alors que le tas de mémoire était déjà rempli. Dans ce cas, la récupération de mémoire s'est produite dans le thread d'allocation.
Explicit
- La récupération de mémoire a été explicitement demandée par une application, par exemple en appelant
System.gc()
ouRuntime.gc()
. Toutefois, comme dans le cas de Dalvik, il est conseillé de laisser la récupération de mémoire s'exécuter quand cela est nécessaire dans ART et d'éviter de demander des récupérations de mémoire explicites, si possible. Les récupérations de mémoire explicites sont déconseillées, car elles bloquent le thread d'allocation et gaspillent inutilement les cycles de processeur. Des récupérations de mémoire explicites peuvent également provoquer des saccades (stuttering, blocages ou arrêts dans l'application) si elles entraînent la préemption d'autres threads. NativeAlloc
- Récupération de mémoire causée par la pression de la mémoire native liée aux allocations natives comme les bitmaps ou les objets d'allocation
RenderScript
. CollectorTransition
- Récupération de mémoire due à une transition de tas de mémoire causée par la modification de la stratégie de récupération de mémoire au moment de l'exécution (par exemple, lorsque l'application passe d'un état de pause perceptible à un état de pause non perceptible). Les transitions de récupération consistent à copier tous les objets d'un espace basé sur une liste libre vers un espace de pointage inversé, ou inversement.
Cela ne se produit que sur les appareils à faible RAM exécutant une version d'Android antérieure à 8.0 lorsqu'une application change d'état de processus en passant d'un état de pause perceptible (par exemple, lorsque l'application est exécutée au premier plan, où l'utilisateur peut voir qu'une pause de récupération de mémoire se produit) à un état de pause non perceptible (ou inversement).
HomogeneousSpaceCompact
- Le compactage d'espace homogène est un compactage entre espace de liste libre et un autre espace de liste libre, qui se produit généralement lorsqu'une application passe à un état de processus de pause non perceptible. Il sert principalement à la réduction de l'utilisation de la RAM et à la défragmentation du tas de mémoire.
DisableMovingGc
- Il ne s'agit pas d'un motif de récupération de mémoire, mais d'une note indiquant que la récupération a été bloquée en raison de l'utilisation de
GetPrimitiveArrayCritical
pendant le compactage simultané du tas de mémoire. En général, l'utilisation deGetPrimitiveArrayCritical
est fortement déconseillée en raison de ses restrictions sur le déplacement des récupérateurs. HeapTrim
- Il ne s'agit pas d'un motif de récupération de mémoire , mais d'une note indiquant que la récupération a été bloquée jusqu'à ce que le traitement d'un tas de mémoire soit achevé.
- Nom de la récupération de mémoire
-
ART peut utiliser différentes récupérations de mémoire :
Concurrent mark sweep (CMS)
- Récupérateur de tas de mémoire complet qui libère et récupère tous les espaces, hormis l'espace d'image.
Concurrent partial mark sweep
- Récupérateur de tas de mémoire presque complet qui récupère tous les espaces, hormis les espaces d'image et de zygotes.
Concurrent sticky mark sweep
- Récupérateur générationnel qui ne peut libérer que des objets alloués depuis la dernière récupération de mémoire. Cette récupération de mémoire s'exécute plus souvent qu'un balayage complet ou partiel de marques, car elle est plus rapide et compte moins de pauses.
Marksweep + semispace
- Récupération de mémoire de copie non simultanée utilisée pour les transitions de tas de mémoire et pour la compression d'espaces homogènes (afin de défragmenter le tas de mémoire).
- Objets libérés
- Nombre d'objets récupérés grâce à cette récupération de mémoire dans l'espace d'objets non volumineux.
- Taille libérée
- Nombre d'octets récupérés grâce à cette récupération de mémoire dans l'espace d'objets non volumineux.
- Objets volumineux libérés
- Nombre d'objets récupérés dans l'espace d'objets volumineux grâce à cette récupération de mémoire.
- Taille d'objets volumineux libérée
- Nombre d'octets récupérés dans l'espace d'objets volumineux grâce à cette récupération de mémoire.
- Statistiques du tas de mémoire
- Quantité (pourcentage) libérée et (nombre d'objets actifs)/(taille totale du tas de mémoire).
- Temps de pause
- En général, les temps de pause sont proportionnels au nombre de références d'objets modifiées pendant l'exécution de la récupération de mémoire. Actuellement, les récupérations de mémoire ART CMS ne comportent qu'une seule pause, vers la fin de la récupération de mémoire. Les récupérations de mémoire en mouvement comportent une longue pause, qui pour la plupart dure tout le temps de la récupération de mémoire.
Si vous constatez une grande quantité de récupérations de mémoire dans Logcat, recherchez les augmentations dans les statistiques des tas de mémoire. Si cette valeur continue d'augmenter et qu'elle ne semble jamais diminuer, il peut s'agir d'une fuite de mémoire.
Si vous constatez une récupération de mémoire qui se produit pour un motif "Alloc", cela signifie que vous êtes déjà proche de votre capacité de tas de mémoire et que des exceptions de saturation de mémoire devraient se produire prochainement.