In Desarrollo y WebSphere Última actualizaciónated:
Comparte en:
Software de Jira es la herramienta de gestión de proyectos número uno utilizada por equipos ágiles para planificar, rastrear, lanzar y respaldar software excelente.

Hablemos sobre el volcado de hilos y cómo analizarlo.

También discutiremos cómo ayuda identificar los problemas y algunos de los analizadores que puede usar.

¿Qué es Thread?

A process es un programa informático que se carga en la memoria del ordenador y se encuentra en ejecución. Puede ser ejecutado por un processo o un conjunto de processors. A process se describe en la memoria con información importante como almacenes de variables, identificadores de archivos, el contador del programa, registros, señales, etc.

A process puede constar de muchos peso ligero processse llama hilos. Esto ayuda a lograr un paralelismo en el que una process se divide en varios hilos. Esto da como resultado un mejor rendimiento. Todos los hilos dentro de un process comparten el mismo espacio de memoria y dependen unos de otros.

Volcados de hilo

Cuando el process se está ejecutando, podemos detectar el st actualate de ejecución del hilos en el process usando volcados de subprocesos. Un volcado de subprocesos contiene una instantánea de todos los subprocesos activos en un punto particular durante la ejecución de un programa. Contiene toda la información relevante sobre el hilo y su estado actual.ate.

Una aplicación moderna hoy en día implica varios subprocesos. Cada hilo requiere ciertos recursos, realiza ciertas actividades related a la process. Esto puede aumentar el rendimiento de una aplicación, ya que los subprocesos pueden utilizar los núcleos de CPU disponibles.

Pero hay compensaciones, por ejemplo, a veces es posible que varios subprocesos no se coordinenate bien entre sí y una situación de punto muerto puederise. Entonces, si algo sale mal, podemos usar volcados de subprocesos para inspect el state de nuestros hilos.

Volcado de hilo en Java

Un volcado de subprocesos JVM es una lista de los state de todos los hilos que forman parte del process en ese momento particular. Contiene información sobre la pila del subproceso, presentada como un seguimiento de la pila. Como está escrito en texto plano, el contenido se puede guardar para revviendo later. El análisis de volcados de subprocesos puede ayudar a

  • Optimización del rendimiento de JVM
  • Optimización del rendimiento de la aplicación
  • Diagnóstico de problemas, por ejemplo, un punto muerto, contención de subprocesos, etc.

Generación de volcados de hilo

Hay muchas maneras de generarate volcados de hilos. A continuación se muestran algunas herramientas basadas en JVM y se pueden ejecutar desde la línea de comandos/terminal (herramientas CLI) o desde /compartimiento (Herramientas GUI) directorio de la carpeta de instalación de Java.

Explorémoslos.

#1. jpila

La forma más sencilla de generarate un volcado de subprocesos se realiza mediante jStack. jStack viene con JVM y se puede utilizar desde la línea de comandos. Aquí necesitamos el PID del process para lo cual queremos generarate el volcado de hilos. Para obtener PID podemos usar jps comando como se muestra a continuación.

jps -l

jps enumera todo java process IDs.

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>

En 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 ~]#

Como podemos ver aquí, obtenemos una lista de todos los java en ejecución. processes. Contiene la identificación de la máquina virtual local para Java en ejecución. process y el nombre de la aplicación en las columnas uno y dos respectivamente. Ahora, para generarate el volcado de hilo, utilizamos el jpila programa con Lo bandera que createsa una larga salida del volcado. También podemos canalizar la salida a algún archivo de texto de nuestra elección.

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 es una herramienta GUI que nos ayuda a solucionar problemas, monitor y profilas aplicaciones Java. También viene con JVM y se puede iniciar desde el /compartimiento directorio de nuestra instalación de java. Es muy intuitivo y fácil de usar. Entre otras opciones, también nos permite capturar volcados de subprocesos para un determinado process.

Para ver el volcado de subprocesos de un tema en particular process, podemos hacer clic derecho en el programa y seleccionar Volcado de hilo desde el menú contextual.

#3. jcmd

JCMD es una utilidad de línea de comandos que se incluye con el JDK y se utiliza para enviar solicitudes de comando de diagnóstico a la JVM.

Sin embargo, solo funciona en la máquina local donde se ejecuta la aplicación Java. Se puede utilizar para controlar las grabaciones de vuelo de Java, diagnosticar y solucionar problemas de aplicaciones Java y JVM. Podemos usar el Thread.print comando de jcmd para obtener una lista de volcados de subprocesos para un particular process especificado por el PID.

A continuación se muestra un ejemplo de cómo podemos usar 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 significa Control de misión de Java. Es una herramienta GUI de código abierto que se envía con JDK y se utiliza para recopilar y analizar datos de aplicaciones Java.

Se puede iniciar desde /compartimiento carpeta de nuestra instalación de Java. Los administradores y desarrolladores de Java utilizan la herramienta para recopilar información detallada de bajo nivel sobre los comportamientos de la aplicación y la JVM. Permite un análisis detallado y eficiente de los datos recopilados por Java. Grabador de vuelo.

Al lanzar jmc, podemos ver la lista de java process que se ejecuta en la máquina local. También es posible una conexión remota. en un particular process, podemos hacer clic derecho y elegir Iniciar grabación de vuelo y luego verifique los volcados de hilo en el Temas .

#5. jconsola

jconsole es una herramienta de extensión de administración de Java utilizada para gestión de reclamaciones y monitoring.

También tiene un conjunto de operaciones predefinidas en el agente JMX que el usuario puede realizar. Permite al usuario detectar y analizar el seguimiento de la pila de un programa en vivo. Se puede iniciar desde /compartimiento carpeta de nuestra instalación de Java.

Usando el jconsola herramienta GUI que podemos inspect el seguimiento de la pila de cada hilo cuando lo conectamos a un java en ejecución process. Luego, en la pestaña Hilo, podemos ver el nombre de todos los hilos en ejecución. Para detectar un punto muerto, podemos hacer clic en el Detectar interbloqueo en la parte inferior derecha del window. Si se detecta un punto muerto, aparecerá en una nueva pestaña, otrawise a No se detectó interbloqueo será mostrado.

#6. SubprocesoMxBean

ThreadMXBean es la interfaz para la gestión del sistema de subprocesos de la máquina virtual Java perteneciente al paquete java.lang.Management. Se utiliza principalmente para detectar los subprocesos que han entrado en una situación de bloqueo y obtener detalles sobre ellos.

Podemos usar la interfaz ThreadMxBean para programarally capturar el volcado del hilo. getThreadMXBean() método de ManagementFactory se usa para obtener una instancia del ThreadMXBean interfaz. Devuelve el número de subprocesos activos tanto demonios como no demonios. ManagementFactory es una clase de fábrica para obtener beans administrados para Java. plat.

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 ();
}

Análisis manual de volcados de hilo

El análisis de volcados de subprocesos puede resultar muy útil para identificar problemas en subprocesos múltiples. processes. Se pueden solucionar problemas como interbloqueos, contención de bloqueos y uso excesivo de CPU por volcados de subprocesos individuales. resolved visualizando el states de volcados de subprocesos individuales.

El rendimiento máximo de la aplicación se puede lograr rectificando el estado de cada hilo después de analizar el volcado del hilo.

En el, digamos, un process está consumiendo mucha CPU, podemos averiguar si algún subproceso está utilizando más la CPU. Si existe tal hilo, convertimos su número LWP a un número hexadecimal. Luego, desde el volcado de subprocesos, podemos encontrar el subproceso con nid igual a prevnúmero hexadecimal obtenido cuidadosamente. Usando el seguimiento de la pila del hilo podemos identificar el problema. Descubramos el process ID del hilo usando el siguiente comando.

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

Echemos un vistazo al siguiente fragmento de volcado de subprocesos. Para obtener el volcado de subprocesos para process 26680, utilice 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

Ahora, veamos cuáles son las cosas que podemos explorar usando volcados de hilo. Si observamos el volcado de subprocesos, podemos ver una gran cantidad de contenido, que puede resultar abrumador. Sin embargo, si damos un paso a la vez, puede ser bastante sencillo de entender. Entendamos la primera línea

2020-06-27 09:01:29
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.221-b11 mixed mode):

Lo anterior muestra la hora en que se generó el volcado.ated, e información sobre la JVM que se utilizó. A continuación, al final, podemos ver la lista de hilos, el primero de ellos es nuestro Controlador de referencia hilo.

Análisis de subprocesos bloqueados

Si analizamos los registros de volcado de subprocesos a continuación, podemos encontrar que ha detectado subprocesos con OBSTRUIDO estado que hace que el rendimiento de una aplicación sea muy lento. Entonces, si podemos encontrar el OBSTRUIDO hilos, podemos intentar extract los hilos related a los bloqueos que los hilos están tratando de obtener. El análisis del seguimiento de la pila del hilo que actualmente contiene el bloqueo puede ayudar a resolver el problema.

[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)
.
.
.
.

Analizando hilo interbloqueado

Otra aplicación muy utilizada de volcados de subprocesos es la detección de puntos muertos. La detección y solución de interbloqueos puede ser mucho más sencilla si analizamos los volcados de subprocesos.

Un interbloqueo es una situación que involucra al menos dos subprocesos en la que el recurso requerido por un subproceso para continuar la ejecución está bloqueado por otro subproceso y, al mismo tiempo, el recurso requerido por el segundo subproceso está bloqueado por el primer subproceso.

Por lo tanto, ninguno de los subprocesos puede continuar la ejecución, y esto da como resultado una situación de interbloqueo y termina con la aplicación atascada. Si hay rastas, la sección final del volcado de hilo imprimirá la información sobre el punto muerto de la siguiente manera.

"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)

Aquí podemos ver la información del interbloqueo en un formato bastante legible por humanos.

Aparte de esto, si resumimos todo el fragmento de volcado de subprocesos anterior, entonces states la siguiente información.

  • Controlador de referencia es el nombre legible por humanos del hilo.
  • #2 es la identificación única del hilo.
  • demonio denota si el hilo es un hilo demonio.
  • La prioridad numérica del hilo viene dada por prio= 10.
  • El estado actual del hilo se denota por esperando en condición.
  • Luego vemos el seguimiento de la pila, que incluye la información de bloqueo.

Analizadores de volcado de hilo

Además del análisis manual, existen numerosas herramientas disponibles para analizar volcados de subprocesos, tanto en línea como fuera de línea. A continuación se muestran algunas de las herramientas enumeradas, que podemos utilizar en función de los requisitos.

Primero, exploremos las herramientas en línea.

#1. Hilo rápido

Hilo rápido son los DevOps la herramienta de análisis de volcado de hilo favorita de los ingenieros para solucionar problemas complejos de producción. Este es un analizador de volcado de subprocesos de Java en línea. Podemos cargar el volcado de subprocesos como un archivo o podemos copiar y pegar directamente el volcado de subprocesos.

Dependiendo del tamaño, analizará el volcado del hilo y mostrará la información como se muestra en la captura de pantalla.

Características

  • Solucionar fallas de JVM, ralentizaciones, fugas de memoria, congelamientos, picos de CPU
  • RCA instantáneo (no espere a los proveedores)
  • Tablero de instrumentos intuitivo
  • Soporte de API REST
  • Aprendizaje automático (Machine learning & LLM)

#2. Analizador de volcado de hilos de Spotify

La Analizador de volcado de hilos de Spotify tiene la licencia de la versión 2.0 de la licencia Apache. Es una herramienta en línea y acepta el volcado de hilo como un archivo o podemos copiar y pegar directamente el volcado de hilo. Dependiendo del tamaño, analizará el volcado del hilo y mostrará la información como se muestra en la captura de pantalla.

#3. jstack revoie

Jpila.revoie analiza los volcados de subprocesos de Java desde dentro del browsejem. Esta página es sólo del lado del cliente.

#4. Sitio web 24 × 7

Esta del IRS es un requisito previo para detectar subprocesos defectuosos que degradan el rendimiento de la máquina virtual Java (JVM). Se pueden solucionar problemas como interbloqueos, contención de bloqueos y uso excesivo de CPU por volcados de subprocesos individuales. resolved visualizando el states de volcados de subprocesos individuales.

El rendimiento máximo de la aplicación se puede lograr rectificando el estado de cada hilo proporcionado por la herramienta.

Ahora, exploremos las herramientas sin conexión.

Cuando se trata de profiling, sólo la mejor herramienta es suficientemente buena.

#1. JProfileer

JProfileer es uno de los analizadores de volcado de subprocesos más populares entre Desarrolladores de Java. JProfiLa interfaz de usuario intuitiva de ler te ayuda resolve cuellos de botella de rendimiento, identificar pérdidas de memoria y comprender los problemas de subprocesos.

JProfisoportes profiling en lo siguiente platformas:

  • Windows
  • macOS
  • Linux
  • FreeBSD
  • Solaris
  • AIX
  • HP-UX

A continuación se presentan algunas características que hacen que JProfiler la mejor opción para profiling nuestras aplicaciones en la JVM.

Características

  • Soporta base de datos profiling para JDBC, JPA y NoSQL
  • Soporte para empresas Javarise La edición también está disponible.
  • Presenta información de alto nivel sobre llamadas RMI
  • Stellar análisis de fugas de memoria
  • Amplias capacidades de control de calidad
  • el integratehilo d profiler está estrechamente integradoated con la CPU profivistas ling.
  • Apoyo a platformularios, IDE y servidores de aplicaciones.

#2. IBM TMDA

Hilo de IBM y Monitor Analizador de volcados para Java (TMDA) es una herramienta que permite la identificación de bloqueos, interbloqueos, contención de recursos y cuellos de botella en volcados de subprocesos de Java. Es un producto de IBM, pero la herramienta TMDA se proporciona sin garantía ni soporte; sin embargo, intentan arreglar y mejorar la herramienta con el tiempo.

#3. ManageEngine

ManageEngine El administrador de aplicaciones puede ayudar a monitor Memoria JVM Heap y Non-Heap. Incluso podemos configurar umbrales y recibir alertas por correo electrónico, SMS, etc., y asegurarnos de que una aplicación Java esté bien sintonizada.

#4. TuKit

TuKit consta de los siguientes productos denominados Kit.

  • Java Profiler: gastos generales bajos con todas las funciones profiler para Java EE y Java SE platformas.
  • TúMonitor - Actuación monitoring y profiling de Jenkins, Team City, Gradle, Maven, Ant, JUnit y TestNG.
  • .NET Profiler: rendimiento y memoria fáciles de usar profiler para .NET framework.

Para Concluir

Ahora ya sabes cómo son útiles los volcados de subprocesos en la comprensión.anding y diagnosticar problemas en aplicaciones multiproceso. Con apropiada local, con respecto a los volcados de subprocesos (su estructura, la información que contienen, etc.), podemos utilizarlos para identificar las causas de los problemas rápidamente.

Comparte en:
  • Asad Ali
    Autor
    Asad es un desarrollador back-end y le encanta escribir sobre growing tecnologías como Kafka, AWS, Docker, NoSQL y API.

Gracias a nuestros patrocinadores

Más lecturas interesantes sobre el desarrollo

Impulse su negocio

Algunas de las herramientas y servicios para ayudar a su negocio grow.
  • La herramienta de conversión de texto a voz que utiliza IA para generarate Voces realistas parecidas a las humanas.

    Intente Murf AI
  • Web scraping, proxy residencial, administrador de proxy, desbloqueador web, rastreador de motores de búsqueda y todo lo que necesita para recopilar datos web.

    Prueba Brightdata
  • Monday.com es un sistema operativo de trabajo todo en uno para ayudarlo a administrar proyectos, tareas, trabajo, ventas, CRM, operaciones, workflows, y más.

    Intente Monday
  • Intruder es un escáner de vulnerabilidades en línea que encuentra debilidades de ciberseguridad en su infraestructura, para evitar costosas filtraciones de datos.

    Intente Intruder