Comment analyser un fichier java thread?

j'essaie d'en savoir plus sur java, en particulier sur la gestion de la mémoire et les threads. Pour cette raison, j'ai récemment trouvé intérêt à regarder les décharges de fil.

voici quelques lignes prises à partir d'une application web en utilisant VisualVM, un outil intégré pour java:

"Finalizer" daemon prio=8 tid=0x02b3d000 nid=0x898 in Object.wait() [0x02d0f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x27ef0288> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
    - locked <0x27ef0288> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

   Locked ownable synchronizers:
    - None

"Reference Handler" daemon prio=10 tid=0x02b3b800 nid=0x494 in Object.wait() [0x02cbf000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x27ef0310> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
    - locked <0x27ef0310> (a java.lang.ref.Reference$Lock)

tout d'abord, j'ai des questions sur quelques noms de variables:

  • que signifie tid et nid?
  • Qu'est-ce que le figure entre parenthèses après L'objet.attendre?

puis pour la pile trace elle-même:

  • qu'est-ce que cela signifie attendre (Java.lang....) et quel est le nombre dans
  • que signifie verrouillé (Java.lang....) même question, ce qui est dans

je pensais que le mot verrouillé était relié d'une façon ou d'une autre à une condition d'attente, cependant, j'avais tort. En fait, je me demande pourquoi verrouillé est répété trois fois, mais le thread est dans l'état runnable comme vu dans le même dump:

"Thread-0" prio=6 tid=0x02ee3800 nid=0xc1c runnable [0x03eaf000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileInputStream.readBytes(Native Method)
    at java.io.FileInputStream.read(FileInputStream.java:199)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
    - locked <0x23963378> (a java.io.BufferedInputStream)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
    - locked <0x23968450> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
    - locked <0x23968450> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at org.codehaus.plexus.util.cli.StreamPumper.run(StreamPumper.java:145)

enfin, c'était le pire d'entre eux:

"CompilerThread0" daemon prio=10 tid=0x02b81000 nid=0x698 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

ce thread est dans l'état runnable, mais il attend à condition. Quelle condition et qu'est-ce que 0x00000?

pourquoi le stack trace est si court sans aucune preuve de la classe thread?

Si vous pouviez répondre à toutes mes questions, je serais très reconnaissant.

Merci

85
demandé sur James Drinkard 2011-09-29 19:21:54

3 réponses

Le TID est thead id et le NID est: Native ID de thread. Cette ID dépend fortement de la plateforme. C'est le NID de jstack thread dumps. Sur Windows, c'est simplement L'ID du thread au niveau OS dans un processus. Sur Linux et Solaris, c'est le PID du thread (qui à son tour est un processus léger). Sur Mac OS X, on dit que C'est la valeur native de pthread_t.

allez à ce lien: Java-level thread ID : pour une définition et une explication plus détaillée de ces deux termes.

sur le site D'IBM j'ai trouvé ce lien: comment interpréter un dump de fil . qui couvre ceci plus en détail:

il explique ce que cette attente signifie: Un verrou empêche plus d'une entité d'accéder à une ressource partagée. Chaque objet en Java™ a une serrure associée (acquise en utilisant un bloc synchronisé ou une méthode). Dans le cas de la JVM, les threads sont en concurrence pour diverses ressources dans la JVM et locks sur Java objet.

décrit ensuite le moniteur comme un type spécial de mécanisme de verrouillage qui est utilisé dans la JVM pour permettre une synchronisation flexible entre les fils. Pour les besoins de cette section, lisez les Termes monitor et lock de façon interchangeable.

puis il va plus loin:

pour éviter d'avoir un moniteur sur chaque objet, la JVM utilise habituellement un drapeau dans un bloc de classe ou de méthode pour indiquer que l'objet est verrouillé. La plupart des le temps, un morceau de code transitera une section verrouillée sans contestation. Par conséquent, le drapeau du gardien est suffisant pour protéger ce morceau de code. Ceci est appelé un écran plat. Cependant, si un autre thread veut accéder à un code qui est verrouillé, une véritable contestation s'est produite. La JVM doit maintenant créer (ou gonfler) l'objet monitor pour maintenir le second thread et mettre en place un mécanisme de signalisation pour coordonner l'accès à la section de code. Ce moniteur est maintenant appelé un gonflés moniteur.

Voici une explication plus approfondie de ce que vous voyez sur les lignes de la thread dump. Un thread Java est implémenté par un thread natif du système d'exploitation. Chaque fil est représenté par une ligne en gras tels que:

" Thread-1 "(TID:0x9017A0, sys_thread_t:0x23EAC8, state:R, native ID:0x6E4) prio=5

*Les 6 éléments suivants explique ce que j'ai trouvé dans l'exemple, les valeurs entre crochets[]:

  1. nom [ Thread-1 ],
  2. identifiant [ 0x9017A0 ],
  3. JVM structure de données d'adresses [ 0x23EAC8 ],
  4. état actuel [ R ],
  5. identifiant du fil natif [ 0x6E4 ],
  6. et priorité [ 5 ].

le "wait on" semble être un fil de démon associé à la jvm elle-même et non le fil d'application perse. Quand vous obtenez un "dans l'Objet.wait ()", ce qui signifie que le fil de démon, "finalizer" ici, est en attente d'une notification à propos d'un verrou sur un objet, dans ce cas, il vous montre quelle notification il attend: "- en attente sur <0x27ef0288> (java.lang.réf.ReferenceQueue $ Lock)"

définition de la suite de référence est: Les files d'attente de référence, auxquelles les objets de référence enregistrés sont ajoutés par le collecteur d'ordures après que les changements appropriés de possibilité d'accès sont détectés.

le thread finalizer fonctionne de sorte que la collecte des ordures fonctionne pour nettoyer les ressources associées à un objet. Si je le vois directement, le finaliseur ne peut pas verrouiller cet objet.: Java.lang.réf.ReferenceQueue.supprimer (ReferenceQueue.java: 118) parce que l'objet java exécute une méthode, donc le thread finalizer est verrouillé jusqu'à ce que cet objet soit terminé avec sa tâche courante.

aussi, le finaliseur ne cherche pas seulement à récupérer de la mémoire, il est plus impliqué que cela pour nettoyer les ressources. J'ai besoin de faire d'étude de plus sur elle, mais si vous avez l'ouverture des fichiers, sockets, etc... lié à des méthodes d'objets, puis le finalizer va travailler sur libérer ces les éléments ainsi.

Quel est le chiffre entre parenthèses après L'objet?attendre dans le thread dump?

C'est un pointeur en mémoire le fil. Voici une description plus détaillée:

C. 4.1 Thread Information

la première partie de la section fil montre le fil qui a provoqué l'erreur fatale, comme suit:

Current thread (0x0805ac88):  JavaThread "main" [_thread_in_native, id=21139]
                    |             |         |            |          +-- ID
                    |             |         |            +------------- state
                    |             |         +-------------------------- name
                    |             +------------------------------------ type
                    +-------------------------------------------------- pointer

le fil pointer est le pointeur vers la structure interne du thread Java VM. Cela ne présente généralement aucun intérêt à moins que vous ne déboguiez un fichier VM ou core Java en direct.

cette dernière description vient de: Guide de dépannage pour Java SE 6 avec HotSpot VM

voici quelques autres liens sur thread dumps:

103
répondu James Drinkard 2018-08-10 02:04:39

suite à l'excellente réponse de @James Drinkard:

notez que, selon l'implémentation sous-jacente, le java .lang.Fil.L'état d'un fil qui est bloqué dans une méthode native peut être rapporté comme RUNNABLE , où A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

il s'avère que cette description englobe également le fait d'être bloqué dans un appel OS tel qu'un sondage ou une opération de lecture - probablement parce qu'il n'y a aucune garantie que la JVM peut sachez quand un appel de méthode native a bloqué au niveau de L'OS.

de nombreuses discussions sur les dumps de threads JVM que j'ai vu soit ignorer complètement cette possibilité, ou bien l'esquiver allègrement sans tenir compte des implications - dont la moindre n'est pas que les outils de surveillance peuvent prêter à confusion en signalant que plusieurs de ces threads sont "en cours d'exécution", et en outre qu'ils fonctionnent tous à 100%.

6
répondu Jeremy 2016-04-06 17:47:35

Try http://fastthread.io

c'est probablement suffisant pour de nombreux cas.

5
répondu Jaskey 2016-11-23 03:14:03