105 votes

Comment analyser un dump de fils java?

Je suis en train d'essayer de comprendre plus au sujet de java, en particulier à propos de la gestion de la mémoire et les threads. Pour cette raison, j'ai récemment trouvé un intérêt dans la recherche au fil des décharges.

Voici quelques lignes d'une application web à l'aide de 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)

D'abord j'ai des questions à propos de certains noms de variables:

  • ce n'tid et le nid veux dire?
  • Qu'est-ce que la figure en carré entre parenthèses après l'Objet.attendre?

Alors pour la trace de la pile elle-même:

  • ce qui signifie en attente sur <.....> (java.lang....) et quel est le nombre de <..>
  • que signifie verrouillé <.....> (java.lang....) même question, ce qui est dans <..>

J'ai pensé que le mot verrouillé était lié d'une certaine manière à une condition d'attente, cependant, j'ai eu tort. En fait, je me demande pourquoi verrouillé est répété trois fois, mais le fil est dans l'état exécutable comme on le voit 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)

Puis le dernier de tous, ce fut le pire d'entre eux:

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

Ce fil est dans l'état exécutable, mais il est en attente sur la condition. Quel état et quel est 0x00000?

Pourquoi la trace de la pile est de courte durée sans aucune preuve de la classe thread?

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

Merci

118voto

James Drinkard Points 2688

Le TID est thead id et le NID est: Native ID de thread. Cet ID est fortement dépendants de la plateforme. C'est le point de démarcation dans jstack fil des décharges. Sur Windows, c'est tout simplement l'OS au niveau de l'ID de thread au sein d'un processus. Sur les systèmes Linux et Solaris, c'est le PID du fils (qui à son tour est un poids léger). Sur Mac OS X, il est dit être le natif pthread_t valeur.

Allez sur ce lien: Java au niveau de l'ID de thread: pour une définition et une explication plus détaillée de ces deux termes.

Sur IBM site, j'ai trouvé ce lien: Comment interpréter un thread dump. que couvre la présente plus en détail:

Il explique ce qu'il attend sur les moyens: Un verrou empêche plus d'une entité d'accéder à une ressource partagée. Chaque objet dans Java™ est associée à un verrou (obtenu en utilisant un bloc synchronisé ou de la méthode). Dans le cas de la JVM, les threads en concurrence pour des ressources diverses dans la JVM et des verrous sur les objets Java.

Il décrit ensuite le moniteur comme un type particulier de mécanisme de verrouillage qui est utilisé dans la JVM pour permettre la flexibilité de synchronisation entre les threads. Pour les fins de cette section, lisez les conditions de surveiller et de verrouiller de façon interchangeable.

Puis il va plus loin:

Pour éviter d'avoir un écran sur chaque objet, la JVM utilise généralement un drapeau dans une classe ou une méthode de bloc pour indiquer que l'élément est verrouillé. La plupart du temps, un morceau de code de transit verrouillés article sans prétention. Par conséquent, le tuteur drapeau est assez pour protéger cette partie du code. Ceci est appelé un écran plat. Toutefois, si un autre thread veut accéder à un code qui est verrouillé, un véritable conflit a eu lieu. La JVM doit maintenant créer (ou à gonfler) le moniteur de l'objet d'organiser la deuxième thread et organiser 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 fil de Java est exécuté par un thread natif du système d'exploitation. Chaque fil est représenté par une ligne en gras, tels que:

"Filetage-1" (TID:0x9017A0, sys_thread_t:0x23EAC8, etat:R, natif ID:0x6E4) prio=5

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

  1. nom [TID:0x9017A0],
  2. identificateur [sys_thread_t],
  3. JVM structure de données d'adresses [0x23EAC8],
  4. état actuel [état:R],
  5. natif des threads identificateur [0x6E4],
  6. et la priorité [prio=5].

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

Définition de la ReferenceQueue est: Référence files d'attente, qui a enregistré objets de référence sont ajoutées par le garbage collector une fois que la joignabilité des modifications sont détectées.

Le finaliseur thread s'exécute donc la collecte des ordures fonctionne pour nettoyer les ressources associées à un objet. Si je vois qu'il corectly, le finaliseur ne pouvez pas obtenir le verrou à cet objet: java.lang.réf.ReferenceQueue.supprimer(ReferenceQueue.java:118) en raison de l'objet java est en cours d'exécution d'une méthode, de sorte que le finaliseur fil est verrouillé jusqu'à ce que l'objet est fini de la tâche actuelle.

Aussi, le finaliseur ne cherche pas seulement à récupérer de la mémoire, c'est plus que pour le nettoyage des ressources. J'ai besoin de faire d'étude de plus sur elle, mais si vous avez l'ouverture des fichiers, sockets, etc... liés à l'un des objets les méthodes, puis le finaliseur va travailler sur la libération des éléments aussi bien.

Qu'est-ce que la figure en carré entre parenthèses après l'Objet.attendre dans le thread dump?

Il s'agit d'un pointeur en mémoire le fil. Voici une description plus détaillée:

C. 4.1 Fil De L'Information

La première partie de la discussion de l'article indique que le thread 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 pointeur est un pointeur vers la machine virtuelle Java filetage interne de la structure. Il est généralement sans intérêt, sauf si vous déboguez un live de la machine virtuelle Java ou fichier de base.

Cette dernière description est venu à partir de: Guide de Dépannage pour Java SE 6 avec HotSpot VM

Voici quelques liens sur le thread dumps:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X