Comment analyser Java discussion Décharges - DZone Performance

Le contenu de cet article a été écrit par Tae Jin Gu sur le blog CUBRID.

Java et discussion

Un serveur web utilise des dizaines à des centaines de threads pour traiter un grand nombre d'utilisateurs simultanés. Si deux ou plusieurs threads utilisent les mêmes ressources, une discorde entre les fils est inévitable, et parfois blocage se produit.







contention de fil est un état dans lequel un fil est en attente d'un verrou, tenu par un autre thread, à soulever. Les différents threads d'accéder fréquemment des ressources partagées sur une application web. Par exemple, pour enregistrer un journal, le fil en essayant d'enregistrer le journal doit obtenir un verrou et d'accéder aux ressources partagées.

Deadlock est un type spécial de contention de fil, dans lequel deux ou plusieurs threads attendent les autres threads pour accomplir leurs tâches afin de compléter leurs propres tâches.

Différents problèmes peuvent surgir de conflit de thread. Pour analyser ces questions, vous devez utiliser la décharge de fil. Un vidage de fil vous donnera les informations sur l'état exact de chaque fil.

Informations générales pour Java Threads

discussion synchronisation

Un fil peut être traité avec d'autres fils en même temps. Afin d'assurer la compatibilité lorsque plusieurs threads tentent d'utiliser des ressources partagées, un fil à la fois devrait être autorisé à accéder aux ressources partagées en utilisant la synchronisation des threads.

La synchronisation des threads sur Java peut être fait en utilisant le moniteur. Chaque objet Java a un seul moniteur. Le moniteur peut appartenir à un seul fil. Pour un fil de posséder un moniteur qui appartient à un autre thread, il a besoin d'attendre dans la file d'attente jusqu'à ce que l'autre thread libère son moniteur.

Statut de la discussion

Afin d'analyser un vidage de fil, vous devez connaître le statut de fils. Les statuts de fils sont indiqués sur java.lang.Thread.State.

Figure 1: Etat des threads.

Types de discussion

threads Java peuvent être divisés en deux:

  1. threads démon;
  2. et des fils de non-démon.

threads daemon cessent de fonctionner quand il n'y a pas d'autres threads non-démon. Même si vous ne créez pas de threads, l'application Java crée plusieurs threads par défaut. La plupart d'entre eux sont des fils démon, principalement pour des tâches de traitement telles que la collecte des ordures ou JMX.

Un fil conducteur de la méthode "static void main (String [] args) » est créé comme un fil non-démon, et quand ce fil cesse de fonctionner, tous les autres fils du démon arrête aussi. (Le fil conducteur de ce procédé principal est appelé le fil VM dans HotSpot VM).

Obtenir un fil Dump

Nous présenterons les trois méthodes les plus couramment utilisées. Notez qu'il ya beaucoup d'autres façons d'obtenir une décharge de fil. Un vidage de fil ne peut montrer l'état de fil au moment de la mesure, donc afin de voir le changement de statut de fil, il est recommandé de les extraire de 5 à 10 fois avec des intervalles de 5 secondes.

Obtenir un vidage de fil à l'aide jstack

Dans JDK 1.6 et plus, il est possible d'obtenir une décharge de fil sur MS Windows en utilisant jstack.

Utilisez PID par JPS pour vérifier le PID du processus d'application Java en cours d'exécution.

Utiliser le PID extraite en tant que paramètre de jstack pour obtenir une décharge de fil.

Un fil Dump L'utilisation jVisualVM

Générer un vidage de fil en utilisant un programme tel que jVisualVM.

Figure 2: Brodeuses Dump utilisant visualvm.

La tâche à gauche indique la liste des processus en cours d'exécution. Cliquez sur le processus pour lequel vous souhaitez les informations, puis sélectionnez l'onglet fil pour vérifier les informations de fil en temps réel. Cliquez sur le bouton de vidage du fil dans le coin supérieur droit pour obtenir le fichier de vidage de fil.

Génération dans un terminal Linux

Obtenir le processus pid en utilisant commande ps -ef pour vérifier le pid du processus Java en cours d'exécution.

Utilisez la en tant que paramètre de -SIGQUIT kill (3) pid extraite pour obtenir une décharge de fil.

Discussion Informations du fil fichier de vidage

  • Nom du thread. Lorsque vous utilisez la classe java.lang.Thread pour générer un fil, le fil sera nommé thread-(Nombre), alors que lors de l'utilisation de classe java.util.concurrent.ThreadFactory, il sera nommé piscine- (nombre) -thread- (nombre ).
  • Priorité. Représente la priorité des threads.
  • ID du sujet. Représente l'ID unique pour les fils. (Quelques informations utiles, y compris l'utilisation du processeur ou utilisation de la mémoire du fil, peut être obtenue en utilisant l'ID de fil).
  • Etat des threads. Représente l'état des fils.
  • Discussion callstack. Représente les informations de pile d'appel des fils.






Discussion modèles Dump par type

Lorsque Impossible d'obtenir un verrou (BLOQUÉ)

C'est quand la performance globale de l'application ralentit car un thread occupe le verrou et empêche les autres threads de l'obtenir. Dans l'exemple suivant, le fil BLOCKED_TEST pool-1-fil-1 est en cours d'exécution avec < 0x0000000780a000b0 > verrouiller, tandis que BLOCKED_TEST pool-1-fil-2 et BLOCKED_TEST threads pool-1-fil-3 sont en attente pour obtenir < 0x0000000780a000b0 > fermer à clé.

Figure 3: Un fil de blocage d'autres fils.

Lorsqu'en état Deadlock

C'est quand le thread A doit obtenir le thread B « verrouillage de continuer sa tâche, alors que le thread B doit obtenir le thread A » verrouillage de continuer sa tâche. Dans la décharge de fil, vous pouvez voir que le fil DEADLOCK_TEST-1 a verrouillage 0x00000007d58f5e48, et tente d'obtenir verrouillage 0x00000007d58f5e60. Vous pouvez aussi voir que le fil DEADLOCK_TEST-2 a serrure 0x00000007d58f5e60, et tente d'obtenir serrure 0x00000007d58f5e78. En outre, le fil DEADLOCK_TEST-3 a verrouillage 0x00000007d58f5e78, et tente d'obtenir verrouillage 0x00000007d58f5e48. Comme vous pouvez le voir, chaque thread est en attente d'obtenir le blocage d'un autre thread, et ce statut ne changera pas jusqu'à ce qu'un filet défausse sa serrure.

Figure 4: Fils dans un état de blocage.

Lorsque vous attendez de recevoir des messages en continu à partir d'un serveur distant

Le fil semble être normal, puisque son état ne cesse de montrer que RUNNABLE. Cependant, lorsque vous alignez le fil dumps par ordre chronologique, vous pouvez voir que le fil socketReadThread attend infiniment à lire la prise.

Figure 5: Statut d'attente continue.

lorsque vous attendez

Le fil est le maintien du statut WAIT. Dans la décharge de fil, le fil IoWaitThread ne cesse d'attendre de recevoir un message de LinkedBlockingQueue. S'il n'y a toujours pas de message pour LinkedBlockingQueue, l'état de fil ne changera pas.

Figure 6: état d'attente.

Lorsque les ressources du sujet ne peut être organisée normalement

les discussions inutiles s'accumuleront lorsque les ressources de fil ne peuvent pas être organisées normalement. Dans ce cas, il est recommandé de surveiller le processus d'organisation de fil ou de vérifier les conditions de résiliation du fil.

Figure 7: Les fils non organisé.

Comment résoudre les problèmes à l'aide de fil Dump

Exemple 1: Lorsque l'utilisation du processeur est anormalement élevé

1. Extraire le fil qui a la plus forte utilisation du processeur.

le plus de l'application, savoir quel fil est en utilisant la CPU.

2. Après l'acquisition de la décharge de fil, vérifier l'action du fil.

Extraire la décharge de fil d'une application avec un PID de 10029, puis trouver le fil avec une JNV de 0x2737.

fil extrait dumps plusieurs fois par heure, et vérifier le changement d'état des discussions pour déterminer le problème.

Exemple 2: Lorsque la performance de traitement est anormalement lente

Après l'acquisition de fil dépotoirs à plusieurs reprises, trouver la liste des discussions avec le statut BLOQUÉ.

Acquérir la liste des sujets ayant le statut BLOQUE après avoir obtenu le fil dépotoirs à plusieurs reprises.

Si les fils sont obstruées, extraire les fils liés à la serrure que les fils tentent d'obtenir.

Grâce à la décharge de fil, vous pouvez confirmer que l'état de fil reste bloqué parce que < 0xe0375410 > serrure ne peut pas être obtenue. Ce problème peut être résolu par l'analyse de la trace de pile à partir du fil qui exerce la serrure.

Il y a deux raisons pour lesquelles le schéma ci-dessus apparaît fréquemment dans les applications utilisant SGBD. La première raison est des configurations inadéquates. En dépit du fait que les fils travaillent encore, ils ne peuvent pas montrer leur meilleure performance car les configurations pour DBCP et autres ne sont pas suffisantes. Si vous extrayez fil dépotoirs plusieurs fois et de les comparer, vous verrez souvent que certains des fils qui ont été bloqués sont déjà dans un état différent.

La deuxième raison est la connexion anormale. Une fois la connexion avec SGBD reste anormal, les threads attendent jusqu'à ce que le temps est écoulé. Dans ce cas, même après l'extraction du fil dumps plusieurs fois et en les comparant, vous verrez que les discussions liées au SGBD sont toujours dans un état BLOQUE. En changeant de manière adéquate les valeurs, telles que la valeur de délai d'attente, vous pouvez raccourcir le temps où le problème se produit.

Codage Easy fil Dump

nommer Threads

Quand un thread est créé en utilisant l'objet java.lang.Thread, le fil sera nommé thread-(Nombre). Quand un thread est créé en utilisant l'objet java.util.concurrent.DefaultThreadFactory, le fil sera nommé piscine- (Nombre) -thread- (Number). Lors de l'analyse des dizaines de milliers de threads pour une application, si tous les fils ont encore leur nom par défaut, leur analyse devient très difficile, car il est difficile de distinguer les fils à analyser.

, Il est donc recommandé de développer l'habitude de nommer les fils à chaque fois qu'un nouveau thread est créé.

Lorsque vous créez un fil à l'aide java.lang.Thread. vous pouvez donner le fil un nom personnalisé en utilisant le paramètre créateur.

Lorsque vous créez un fil à l'aide java.util.concurrent.ThreadFactory. vous pouvez le nommer en générant votre propre ThreadFactory. Si vous n'avez pas besoin de fonctionnalités spécifiques, vous pouvez utiliser MyThreadFactory comme décrit ci-dessous:

Obtenir des informations plus détaillées à l'aide MBean

Vous pouvez obtenir des objets à l'aide ThreadInfo MBean. Vous pouvez également obtenir plus d'informations qui seraient difficiles à acquérir par le biais des décharges de fil, en utilisant ThreadInfo.

Vous pouvez acquérir la quantité de temps que les fils d'attente ou le ont été bloqués en utilisant la méthode en ThreadInfo et en utilisant cela, vous pouvez également obtenir la liste des sujets qui ont été inactifs pendant une période anormalement longue.

En conclusion







Articles Liés