Qu'est-ce que Thread Dump et comment les analyser?

Parlons du thread dump et comment l'analyser.
Nous discuterons également de la manière dont cela aide à identifier les problèmes et certains des analyseurs que vous pouvez utiliser.
Qu'est-ce que le fil ?
A process est un programme informatique chargé dans la mémoire de l'ordinateur et en cours d'exécution. Il peut être exécuté par un processou ou un ensemble de processous. UN process est décrit en mémoire avec des informations importantes telles que les magasins de variables, les descripteurs de fichiers, le compteur de programme, les registres, les signaux, etc.
A process peut être constitué de nombreux poids légers processon s'appelle discussions. Cela permet d'obtenir un parallélisme dans lequel un process est divisé en plusieurs threads. Il en résulte de meilleures performances. Tous les fils d'un process partagent le même espace mémoire et dépendent les uns des autres.
Dumps de thread
When the process est en cours d'exécution, nous pouvons détecter le st actuelate d'exécution de la fils dans le process utiliser des thread dumps. Un thread Dump contient un instantané de tous les threads actifs à un moment donné lors de l'exécution d'un programme. Il contient toutes les informations pertinentes sur le fil et son état actuel.ate.
Aujourd’hui, une application moderne implique plusieurs nombres de threads. Chaque thread nécessite certaines ressources, effectue certaines activités related au process. Cela peut améliorer les performances d'une application, car les threads peuvent utiliser les cœurs de processeur disponibles.
Mais il y a des compromis à faire, par exemple, parfois plusieurs threads ne peuvent pas être coordonnés.ate bien les uns avec les autres et une situation de blocage peutrise. Ainsi, si quelque chose ne va pas, nous pouvons utiliser des thread dumps pour inspect le state de nos fils.
Vidage de thread en Java
Un thread Dump JVM est une liste des state de tous les fils de discussion qui font partie du process à ce moment précis. Il contient des informations sur la pile du thread, présentées sous forme de trace de pile. Comme il est écrit en clair, le contenu peut être enregistré pour revregarder later. L'analyse des thread dumps peut aider à
- Optimiser les performances de la JVM
- Optimisation des performances de l'application
- Diagnostiquer des problèmes, par exemple un blocage, un conflit de threads, etc.
Génération de thread dumps
Il existe de nombreuses façons de générerate vidages de threads. Vous trouverez ci-dessous quelques outils basés sur JVM et pouvant être exécutés à partir de la ligne de commande/du terminal (outils CLI) ou du / bin (GUI tools) répertoire du dossier d'installation de Java.
Explorons-les.
# 1. jStackName
La manière la plus simple de générerate un thread dump s'effectue en utilisant jStack. jStack est livré avec JVM et peut être utilisé à partir de la ligne de commande. Ici, nous avons besoin du PID du process pour lequel nous voulons générerate le vidage de thread. Pour obtenir le PID, nous pouvons utiliser JPS comme indiqué ci-dessous.
jps -l
jps
répertorie tous les java process identifiants.
On Windows
C:\Program Files\Java\jdk1.8.0_171\bin>jps -l
47172 portal
6120 sun.tools.jps.Jps
C:\Program Files\Java\jdk1.8.0_171\bin>
Sous Linux
[geekfkare@localhost ~]# jps -l
1088 /opt/keycloak/jboss-modules.jar
26680 /var/lib/jenkins/workspace/kyc/kyc/target/kyc-1.0.jar
7193 jdk.jcmd/sun.tools.jps.Jps
2058 /usr/share/jenkins/jenkins.war
11933 /var/lib/jenkins/workspace/admin-portal/target/portal-1.0.jar
[geekfkare@localhost ~]#
Comme nous pouvons le voir ici, nous obtenons une liste de tous les Java en cours d'exécution. processes. Il contient l'identifiant de la VM locale pour Java en cours d'exécution. process et le nom de l'application dans les colonnes un et deux respectivement. Maintenant, pour générerate le thread dump, nous utilisons le jStackName programme avec Il drapeau qui créeatec'est une sortie longuement répertoriée du dump. Nous pouvons également diriger la sortie vers un fichier texte de notre choix.
jstack -l 26680<br>
[geekfkare@localhost ~]# jstack -l 26680
2020-06-27 06:04:53
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.221-b11 mixed mode):
"Attach Listener" #16287 daemon prio=9 os_prio=0 tid=0x00007f0814001800 nid=0x4ff2 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"logback-8" #2316 daemon prio=5 os_prio=0 tid=0x00007f07e0033000 nid=0x4792 waiting on condition [0x00007f07baff8000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006ca9a1fc0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"logback-7" #2315 daemon prio=5 os_prio=0 tid=0x00007f07e0251800 nid=0x4791 waiting on condition [0x00007f07bb0f9000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006ca9a1fc0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
# 2. jvisualvm
Jvisualvm est un outil GUI qui nous aide à dépanner, monitoret profiles applications Java. Il est également livré avec JVM et peut être lancé depuis le / bin répertoire de notre installation Java. C’est très intuitif et facile à utiliser. Entre autres options, cela nous permet également de capturer le thread dump pour un process.
Pour afficher le thread dump d'un sujet particulier process, nous pouvons faire un clic droit sur le programme et sélectionner Décharge de thread dans le menu contextuel.

# 3. jcmd
JCMD est un utilitaire de ligne de commande livré avec le JDK et utilisé pour envoyer des requêtes de commande de diagnostic à la JVM.
Il ne fonctionne cependant que sur la machine locale sur laquelle l'application Java est en cours d'exécution. Il peut être utilisé pour contrôler les enregistrements de vol Java, diagnostiquer et dépanner les applications JVM et Java. Nous pouvons utiliser le Thread.print
commande de jcmd pour obtenir une liste des thread dumps pour un process spécifié par le PID.
Voici un exemple de la façon dont nous pouvons utiliser jcmd
.
jcmd 28036 Thread.print
C:\Program Files\Java\jdk1.8.0_171\bin>jcmd 28036 Thread.print
28036:
2020-06-27 21:20:02
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode):
"Bundle File Closer" #14 daemon prio=5 os_prio=0 tid=0x0000000021d1c000 nid=0x1d4c in Object.wait() [0x00000000244ef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.getNextEvent(EventManager.java:403)
- locked <0x000000076f380a88> (a org.eclipse.osgi.framework.eventmgr.EventManager$EventThread)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:339)
"Active Thread: Equinox Container: 0b6cc851-96cd-46de-a92b-253c7f7671b9" #12 prio=5 os_prio=0 tid=0x0000000022e61800 nid=0xbff4 waiting on condition [0x00000000243ee000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076f388188> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000021a7b000 nid=0x2184 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #9 daemon prio=9 os_prio=2 tid=0x00000000219f5000 nid=0x1300 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x00000000219e0000 nid=0x48f4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x00000000219df000 nid=0xb314 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x00000000219db800 nid=0x2260 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000219d9000 nid=0x125c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000000219d8000 nid=0x834 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001faf3000 nid=0x36c0 in Object.wait() [0x0000000021eae000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076f390180> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
- locked <0x000000076f390180> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000005806000 nid=0x13c0 in Object.wait() [0x00000000219af000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076f398178> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Unknown Source)
at java.lang.ref.Reference.tryHandlePending(Unknown Source)
- locked <0x000000076f398178> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
"main" #1 prio=5 os_prio=0 tid=0x000000000570e800 nid=0xbf8 runnable [0x0000000000fec000]
java.lang.Thread.State: RUNNABLE
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(Unknown Source)
at java.util.zip.ZipFile.<init>(Unknown Source)
at java.util.zip.ZipFile.<init>(Unknown Source)
at org.eclipse.osgi.framework.util.SecureAction.getZipFile(SecureAction.java:307)
at org.eclipse.osgi.storage.bundlefile.ZipBundleFile.getZipFile(ZipBundleFile.java:136)
at org.eclipse.osgi.storage.bundlefile.ZipBundleFile.lockOpen(ZipBundleFile.java:83)
at org.eclipse.osgi.storage.bundlefile.ZipBundleFile.getEntry(ZipBundleFile.java:290)
at org.eclipse.equinox.weaving.hooks.WeavingBundleFile.getEntry(WeavingBundleFile.java:65)
at org.eclipse.osgi.storage.bundlefile.BundleFileWrapper.getEntry(BundleFileWrapper.java:55)
at org.eclipse.osgi.storage.BundleInfo$Generation.getRawHeaders(BundleInfo.java:130)
- locked <0x000000076f85e348> (a java.lang.Object)
at org.eclipse.osgi.storage.BundleInfo$CachedManifest.get(BundleInfo.java:599)
at org.eclipse.osgi.storage.BundleInfo$CachedManifest.get(BundleInfo.java:1)
at org.eclipse.equinox.weaving.hooks.SupplementerRegistry.addSupplementer(SupplementerRegistry.java:172)
at org.eclipse.equinox.weaving.hooks.WeavingHook.initialize(WeavingHook.java:138)
at org.eclipse.equinox.weaving.hooks.WeavingHook.start(WeavingHook.java:208)
at org.eclipse.osgi.storage.FrameworkExtensionInstaller.startActivator(FrameworkExtensionInstaller.java:261)
at org.eclipse.osgi.storage.FrameworkExtensionInstaller.startExtensionActivators(FrameworkExtensionInstaller.java:198)
at org.eclipse.osgi.internal.framework.SystemBundleActivator.start(SystemBundleActivator.java:112)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:815)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:808)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:765)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1005)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule.initWorker(EquinoxBundle.java:190)
at org.eclipse.osgi.container.SystemModule.init(SystemModule.java:99)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle.init(EquinoxBundle.java:272)
at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle.init(EquinoxBundle.java:257)
at org.eclipse.osgi.launch.Equinox.init(Equinox.java:171)
at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:316)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:251)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:661)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:597)
at org.eclipse.equinox.launcher.Main.run(Main.java:1476)
"VM Thread" os_prio=2 tid=0x000000001fae8800 nid=0x32cc runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000005727800 nid=0x3264 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000005729000 nid=0xbdf4 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000572a800 nid=0xae6c runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000572d000 nid=0x588 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x000000000572f000 nid=0xac0 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000005730800 nid=0x380 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000005733800 nid=0x216c runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000005734800 nid=0xb930 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x0000000021a8d000 nid=0x2dcc waiting on condition
JNI global references: 14
C:\Program Files\Java\jdk1.8.0_171\bin>
# 4. JMC
JMC signifie Contrôle de mission Java. Il s'agit d'un outil d'interface graphique open source fourni avec JDK et utilisé pour collecter et analyser les données d'application Java.
Il peut être lancé depuis le / bin dossier de notre installation Java. Les administrateurs et développeurs Java utilisent l'outil pour recueillir des informations détaillées de bas niveau sur les comportements de la JVM et de l'application. Il permet une analyse détaillée et efficace des données collectées par Java Enregistreur de vol.
Au lancement jmc
, nous pouvons voir la liste de Java process qui s'exécute sur la machine locale. Une connexion à distance est également possible. Sur un particulier process, nous pouvons faire un clic droit et choisir Démarrer l'enregistrement de vol puis vérifiez les décharges de thread dans le Threads languette.

# 5. jconsole
jconsole est un outil Java Management Extension utilisé pour gestion des réclamations et le monitorING.
Il dispose également d'un ensemble d'opérations prédéfinies sur l'agent JMX que l'utilisateur peut effectuer. Il permet à l'utilisateur de détecter et d'analyser la trace de pile d'un programme en direct. Il peut être lancé depuis le / bin dossier de notre installation Java.
Le jconsole Outil GUI que nous pouvons inspect la trace de la pile de chaque thread lorsque nous le connectons à un Java en cours d'exécution process. Ensuite, dans l'onglet Thread, nous pouvons voir le nom de tous les threads en cours d'exécution. Pour détecter un blocage, on peut cliquer sur le Détecter le blocage en bas à droite du window. Si un blocage est détecté, il apparaîtra dans un nouvel onglet autrewise a Aucun blocage détecté Sera affiché.

# 6. DiscussionMxBean
ThreadMXBean est l'interface de gestion du système de threads de la machine virtuelle Java appartenant au package java.lang.Management. Il est principalement utilisé pour détecter les threads qui sont entrés dans une situation de blocage et obtenir des détails à leur sujet.
Nous pouvons utiliser l'interface ThreadMxBean pour programmerally capturer le thread dump. getThreadMXBean()
méthode de ManagementFactory
est utilisé pour obtenir une instance de ThreadMXBean
interface. Il renvoie le nombre de threads actifs démons et non démons. ManagementFactory est une classe d'usine permettant d'obtenir les beans gérés pour Java platformulaire.
private static String getThreadDump (boolean lockMonitors, boolean lockSynchronizers) {
StringBuffer threadDump = new StringBuffer (System.lineSeparator ());
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean ();
for (ThreadInfo threadInfo : threadMXBean.dumpAllThreads (lockMonitors, lockSynchronizers)) {
threadDump.append (threadInfo.toString ());
}
return threadDump.toString ();
}
Analyse manuelle des vidages de threads
L'analyse des thread dumps peut être très utile pour identifier les problèmes dans les environnements multithread. processes. Des problèmes tels que les blocages, les conflits de verrouillage et l'utilisation excessive du processeur par des vidages de threads individuels peuvent être resolved en visualisant le states de dumps de threads individuels.
Le débit maximal de l'application peut être atteint en rectifiant l'état de chaque thread après avoir analysé le vidage de thread.
Par exemple, disons, un process utilise beaucoup de CPU, nous pouvons savoir si un thread utilise le plus le CPU. S'il existe un tel thread, nous convertissons son numéro LWP en nombre hexadécimal. Ensuite, à partir du thread dump, nous pouvons trouver le thread avec nid égal au prevnombre hexadécimal obtenu avec soin. En utilisant la trace de pile du thread, nous pouvons identifier le problème. Découvrons le process identifiant du thread à l’aide de la commande ci-dessous.
ps -mo pid,lwp,stime,time,cpu -C java
[geekfkare@localhost ~]# ps -mo pid,lwp,stime,time,cpu -C java
PID LWP STIME TIME %CPU
26680 - Dec07 00:02:02 99.5
- 10039 Dec07 00:00:00 0.1
- 10040 Dec07 00:00:00 95.5
Jetons un coup d'œil au morceau ci-dessous du vidage de thread. Pour obtenir un thread dump pour process 26680, utiliser jstack -l 26680
[geekfkare@localhost ~]# jstack -l 26680
2020-06-27 09:01:29
<strong>Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.221-b11 mixed mode):</strong>
"Attach Listener" #16287 daemon prio=9 os_prio=0 tid=0x00007f0814001800 nid=0x4ff2 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
.
.
.
.
.
.
.
"<strong>Reference Handler</strong>" #2 daemon prio=10 os_prio=0 tid=0x00007f085814a000 nid=0x6840 in Object.wait() [0x00007f083b2f1000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000006c790fbd0> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=0 tid=0x00007f0858140800 nid=0x683f runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f0858021000 nid=0x683b runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f0858022800 nid=0x683c runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f0858024800 nid=0x683d runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f0858026000 nid=0x683e runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f08581a0000 nid=0x6847 waiting on condition
JNI global references: 1553
Voyons maintenant quelles sont les choses que nous pouvons explorer à l'aide de threads dumps. Si nous observons le vidage des threads, nous pouvons voir beaucoup de contenu, ce qui peut être écrasant. Cependant, si nous faisons un pas à la fois, cela peut être assez simple à comprendre. Comprenons la première ligne
2020-06-27 09:01:29
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.221-b11 mixed mode):
Ce qui précède affiche l'heure à laquelle le dump a été généréated et des informations sur la JVM utilisée. Ensuite, à la fin, nous pouvons voir la liste des discussions, la première d'entre elles est notre Gestionnaire de référence fil.
Analyse des threads bloqués
Si nous analysons les journaux de vidage de thread ci-dessous, nous pouvons constater qu'il a détecté des threads avec BLOQUÉ statut qui rend les performances d'une application très lentes. Donc, si nous pouvons trouver le BLOQUÉ fils de discussion, nous pouvons essayer de extract des discussions related aux verrous que les threads tentent d'obtenir. L'analyse de la trace de pile du thread détenant actuellement le verrou peut aider à résoudre le problème.
[geekfkare@localhost ~]# jstack -l 26680
.
.
.
.
" DB-Processor-13" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f000]
java.lang.Thread.State: <strong>BLOCKED</strong> (on object monitor)
at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
- waiting to lock <0xe0375410> (a beans.ConnectionPool)
at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)
"DB-Processor-14" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f020]
java.lang.Thread.State: <strong>BLOCKED</strong> (on object monitor)
at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
- waiting to lock <0xe0375410> (a beans.ConnectionPool)
at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)
.
.
.
.
Analyse d'un thread bloqué
Une autre application très courante des thread dumps est la détection de impasses. La détection et la résolution des blocages peuvent être beaucoup plus faciles si nous analysons les décharges de threads.
Un blocage est une situation impliquant au moins deux threads où la ressource requise par un thread pour continuer l'exécution est verrouillée par un autre thread et en même temps, la ressource requise par le second thread est verrouillée par le premier thread.
Ainsi, aucun des threads ne peut continuer l'exécution, ce qui entraîne une situation de blocage et le blocage de l'application. Si des dreadlocks sont présents, la dernière section du thread dump imprimera les informations concernant le blocage comme suit.
"Thread-0":
waiting to lock monitor 0x00000250e4982480 (object 0x00000000894465b0, a java.lang.Object),
which is held by "Thread-1"
"Thread-1":
waiting to lock monitor 0x00000250e4982380 (object 0x00000000894465a0, a java.lang.Object),
which is held by "Thread-0"
.
.
.
"Thread-0":
at DeadlockedProgram$DeadlockedRunnableImplementation.run(DeadlockedProgram.java:34)
- waiting to lock <0x00000000894465b0> (a java.lang.Object)
- locked <0x00000000894465a0> (a java.lang.Object)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
"Thread-1":
at DeadlockedProgram $DeadlockRunnableImplementation.run(DeadlockedProgram.java:34)
- waiting to lock <0x00000000894465a0> (a java.lang.Object)
- locked <0x00000000894465b0> (a java.lang.Object)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
Ici, nous pouvons voir les informations de blocage dans un format assez lisible par l'homme.
En dehors de cela, si nous résumons ensemble tous les morceaux de thread dump ci-dessus, alors cela resteateVoici les informations ci-dessous.
- Gestionnaire de référence est le nom lisible par l'homme du thread.
- #2 est l'identifiant unique du thread.
- démon indique si le thread est un thread démon.
- La priorité numérique du thread est donnée par prio= 10.
- L'état actuel du thread est indiqué par attente sous condition.
- Ensuite, nous voyons la trace de la pile, qui comprend les informations de verrouillage.
Analyseurs de vidages de threads
Outre l'analyse manuelle, il existe de nombreux outils disponibles pour analyser les threads, à la fois en ligne et hors ligne. Vous trouverez ci-dessous certains des outils répertoriés, que nous pouvons utiliser en fonction des besoins.
Tout d'abord, explorons les outils en ligne.
# 1. Fil rapide
Filetage rapide est DevOps l'outil d'analyse de vidage de thread préféré de l'ingénieur pour résoudre les problèmes de production complexes. Il s'agit d'un analyseur de vidage de thread Java en ligne.Nous pouvons télécharger le vidage de thread en tant que fichier ou nous pouvons directement copier et coller le vidage de thread.
En fonction de la taille, il analysera le vidage de thread et affichera les informations comme indiqué dans la capture d'écran.

FONCTIONNALITÉS
- Dépanner les plantages JVM, les ralentissements, les fuites de mémoire, les blocages, les pics de processeur
- RCA instantané (n'attendez pas les fournisseurs)
- Tableau de bord intuitif
- Prise en charge de l'API REST
- Machine Learning
# 2. Analyseur de vidage de thread Spotify
La Analyseur de vidage de thread Spotify est sous licence sous la version 2.0 de la licence Apache. C'est un outil en ligne et accepte le thread dump sous forme de fichier ou nous pouvons directement copier et coller le thread dump. En fonction de la taille, il analysera le vidage du thread et affichera les informations comme indiqué dans la capture d'écran.

# 3. Jstack revIEW
Jstack.revIEW analyse les dumps de threads Java depuis le browseuh. Cette page est uniquement côté client.

# 4. Site Web 24 × 7
Cette outil est une condition préalable à la détection des threads défectueux dégradant les performances de la machine virtuelle Java (JVM). Des problèmes tels que les blocages, les conflits de verrouillage et l'utilisation excessive du processeur par des vidages de threads individuels peuvent être resolved en visualisant le states de dumps de threads individuels.
Le débit maximal de l'application peut être atteint en rectifiant l'état de chaque thread fourni par l'outil.

Maintenant, explorons les outils hors ligne.
Si vous préférez profiLing, seul le meilleur outil est suffisant.
# 1. JProfiler
JProfiler est l'un des analyseurs de vidage de thread les plus populaires parmi Développeurs Java. JProfil'interface utilisateur intuitive de ler vous aide resolve les goulots d'étranglement des performances, identifier les fuites de mémoire et comprendre les problèmes de threading.

JProfiler prend en charge profije m'attarde sur ce qui suit platformes:
- Windows
- macOS
- Linux
- FreeBSD
- Solaris
- AIX
- HP-UX
Vous trouverez ci-dessous quelques fonctionnalités qui font de JProfiler le premier choix pour profiinstaller nos applications sur la JVM.
FONCTIONNALITÉS
- Prend en charge la base de données profiling pour JDBC, JPA et NoSQL
- Prise en charge de Java Enterpriserise l'édition est également disponible
- Présente des informations de haut niveau sur les appels RMI
- Stellar analyse des fuites de mémoire
- Capacités d'assurance qualité étendues
- L'intégratefil de discussion profiler est étroitement intégréated avec le CPU profivues ling.
- Support pour platformulaires, IDE et serveurs d'applications.
# 2. IBMTMDA
Discussion IBM et Monitor Analyseur de vidage pour Java (TMDA) est un outil qui permet d'identifier les blocages, les blocages, les conflits de ressources et les goulots d'étranglement dans les vidages de thread Java. Il s'agit d'un produit IBM mais l'outil TMDA est fourni sans aucune garantie ni assistance; cependant, ils essaient de réparer et d'améliorer l'outil au fil du temps.

# 3. ManageEngine
ManageEngine le gestionnaire d'applications peut vous aider à monitor Mémoire JVM Heap et non-Heap. Nous pouvons même configurer des seuils et être alertés par email, SMS, etc., et nous assurer qu'une application Java est bien réglée.

# 4. VotreTrousse
VotreTrousse se compose des produits ci-dessous appelés sous forme de kit.
- Java Profiler – Fonctionnalités complètes et faibles frais généraux profilecteur pour Java EE et Java SE platformes.
- VousMonitor - Performance monitoring et profiling de Jenkins, Team City, Gradle, Maven, Ant, JUnit et TestNG.
- .NET Profiler – Performances et mémoire faciles à utiliser profiler pour le framework .NET.
Conclusion
Vous savez maintenant à quel point les thread dumps sont utiles pour comprendreanding et diagnostiquer les problèmes dans les applications multithread. Avec le bon le savoir, concernant les thread dumps - leur structure, les informations qu'ils contiennent, etc. - nous pouvons les utiliser pour identifier rapidement les causes des problèmes.