Objectif

Analysez les images mémoire des threads Java AEM à l’aide de l’outil IBM Thread Analyzer.

Étapes

  1. Téléchargez et installez IBM Thread Analyzer (par souci de concision, nous l’appellerons IBM TDA).
  2. Capture des images mémoire de threads à partir d’une instance AEM rencontrant des problèmes de performances.
  3. Ouvrez les images mémoire de threads dans IBM TDA.
  4. Pour afficher les détails d’une image mémoire de thread, sélectionnez le fichier dans la liste, puis cliquez sur le bouton « Détail du thread »*.
tda-threaddetail
  1. Effectuez un tri par « profondeur de pile » avec les plus longues piles s’affichant en priorité.
tda-image1
  1. Examinez les threads avec une profondeur de pile d’au moins 10 lignes.  Ce sont généralement les threads les plus intéressants.  Prenez des notes sur les threads intéressants.
  2. Triez par « état » de thread.
  3. Faites défiler les threads « exécutables ». Les threads exécutables sont ceux qui ont mobilisé activement le temps du processeur lors de la capture d’image mémoire de thread.

Remarque : lors de l’examen des threads « exécutables », vous pouvez ignorer les threads répertoriés dans la section Threads pouvant être ignorés, en bas de cette page.

  1. Trouvez les threads exécutables qui font partie de l’application, comme les threads de tâche en arrière-plan ou les threads de requête. (Les threads de requête portent des noms similaires à l’exemple suivant : 127.0.0.1 [1347028187737] GET /content/sites/global/en/sitemap.static-delivery.httpd.html HTTP/1.1.) Lorsque vous les avez trouvés, cliquez dessus l’un après l’autre.
  2. Pour chaque thread de requête, vous pouvez identifier à quel moment le navigateur de l’utilisateur a envoyé la requête au serveur, en examinant l’horodatage dans le nom du thread.  Par exemple, dans le nom du thread ci-dessus, l’horodatage (format epoch Unix en millisecondes) affiche 1347028187737. Nous pouvons convertir ce numéro epoch en une date et une heure à l’aide de www.epochconverter.com.  Chaque image mémoire de thread indique la date et l’heure à laquelle elle a été prise.  Vous pouvez mesurer la différence entre l’heure de la requête et l’heure de l’image mémoire de thread pour savoir pendant combien de temps la requête a été active.
  3. Après avoir examiné les threads de requête, faites défiler les autres threads « exécutables ».  Lorsque vous avez trouvé un thread « exécutable » intéressant, examinez le volet central, « Threads en attente ».  Les threads qui y sont répertoriés attendent que le thread sélectionné libère un moniteur.  Si vous ne voyez aucun thread en attente, celui sélectionné pourrait posséder un Cadenas (pour plus de détails, voir les classes d’implémentation de Cadenas). Par exemple, avec un ReentrantReadWriteLock, il est impossible de déterminer quel thread possède le cadenas puisque les cadenas gèrent plusieurs moniteurs en interne.  Vous pourriez donc devoir examiner le code source pour l’associer à un thread susceptible d’être le détenteur du code.
  4. Si le thread présentait un cadenas ou un moniteur dont de nombreux autres threads se servaient, parcourez le reste des images mémoire de thread pour identifier d’autres threads présentant le même problème.  Si le même thread existe toujours dans d’autres images mémoire (dans IBM TDA, vous pouvez sélectionner différentes images mémoire de thread), puis cliquez sur le bouton « Comparer les threads »* pour afficher l’état d’un thread sur différentes images mémoire de threads.
tda-comparethreads
  1. Regardez le thread Collector Service dans la capture d’écran ci-dessous :
tda-Image2
  1. Dans cet affichage, vous pouvez voir le thread sur plusieurs images mémoire de thread pour déterminer s’il s’agit d’un thread à longue exécution.  En règle générale, si le thread est à l’état Exécutable sur plusieurs images mémoire et qu’il présente une longue pile, cela signifie généralement qu’il s’agit d’un thread à longue exécution.
  2. Si votre recherche dans les threads exécutables a été infructueuse, retournez à la liste des threads, sélectionnez une image mémoire de thread, puis cliquez sur le bouton « Détail du moniteur »*, dans le volet supérieur. IBM TDA ouvre alors une fenêtre indiquant une arborescence du moniteur possédant des threads ainsi que les threads en attente. Remarque : il se pourrait que certains threads de pools de threads s’affichent, comme le moniteur de pool de thread du moteur servlet ; les threads inactifs peuvent être ignorés.  Vous pouvez généralement déterminer si un thread est un thread de pool de thread inactif car ceux-ci ne comportent que 10 lignes de pile au maximum.
tda-monitordetail
  1. Sur le volet supérieur, cliquez sur le bouton « Trouver des threads à exécution longue » (ce bouton présente une icône avec des jumelles).
  2. En bas à gauche, vous voyez désormais une nouvelle icône après les images mémoire de threads. Cliquez dessus pour voir les threads à exécution longue.
  3. Triez-les à nouveau par « état » dans le volet de droite.
  4. Faites défiler les threads exécutables pour identifier les threads qui étaient actifs lors des images mémoire.
Utilisation du processeur au niveau du thread (plateforme Linux uniquement) :
  1. Si vous obtenez le résultat « top -H -b -n1 -p <javapid> » en plus des images mémoire de threads, vous pouvez effectuer une référence croisée pour l’utilisation du processeur au niveau du thread.  Ouvrez le résultat en tête de liste pour obtenir les ID de processus des threads utilisant le processeur.  Convertissez l’ID de processus en valeur hexadécimale, puis recherchez-la dans le fichier d’image mémoire de thread correspondant.  L’ID doit correspondre au « nid » de l’un des threads.
  2. Si le thread correspondant qui utilise le plus le processeur est le « Thread VM » ou un thread de nettoyage de mémoire, il se pourrait que vous ayez un problème de mémoire.  Répétez le même exercice avec les autres images mémoire de thread et le résultat en tête de liste, et si vous obtenez un schéma de ces threads mobilisant le temps du processeur, vous êtes face à un problème de mémoire.
  3. Si vous avez vérifié le problème de mémoire, capturez une image mémoire des segments de mémoire la prochaine fois que le problème survient.  Pour plus de détails sur la capture et l’analyse des images mémoire des segments de mémoire, consultez cet article.

Threads pouvant être ignorés :

  • Thread VM : il s’agit d’un thread de système VM.
  • Threads commençant par un thread de tâche de nettoyage de mémoire : il s’agit de threads de nettoyage de mémoire.
  • Threads avec des noms similaires à [1347028691218] dans le code au niveau de java.net.PlainSocketImpl.socketAccept(Native Method) : il s’agit de threads provenant du pool de thread du serveur servlet en attente de nouvelles connexions.

Ce produit est distribué sous licence Creative Commons Attribution - Pas d’utilisation commerciale - Partage à l’identique 3.0 non transposé  Les publications Twitter™ et Facebook ne sont pas couvertes par les dispositions Creative Commons.

Mentions légales   |   Politique de confidentialité en ligne