Jstack se utiliza para imprimir la información de Java Stack de una identificación de proceso Java dada o archivo central o servicio de depuración remota. Si está en una máquina de 64 bits, debe especificar la opción "-J-D64". El uso de Windows Jstack solo admite los siguientes métodos:
jstack [-l] [f] pid
Si un programa Java se bloquea para generar un archivo central, la herramienta JSTACK se puede usar para obtener información sobre la pila Java y la pila nativa del archivo central, para que pueda saber fácilmente cómo se bloquea el programa Java y dónde el programa es problemático. Además, la herramienta Jstack también se puede adjuntar al programa Java en ejecución y ver la información sobre la pila Java y la pila nativa del programa Java que se estaba ejecutando en ese momento. Si el programa Java en ejecución ahora hace que el estado de colgada, Jstack sea muy útil. Si el proceso está en un estado muerto de colgado, puede forzar la pila que se juegue con -f.
En el archivo de volcado, el estado del hilo que vale la pena prestar atención es:
Deadlock, punto muerto (enfoque en)
Corredor
Esperando la condición (concéntrese en)
Esperando la entrada del monitor (concéntrese)
Suspendido
Object Waiting, Object.Wait () o Timed_Waiting
Bloqueado, bloqueado (enfocado)
Parar, estacionado
Eché un vistazo a tres escenarios de otro blog:
Ejemplo 1: esperando bloquear y bloqueado
"Conexión RMI TCP (267865) -172.16.5.25" Daemon PRIO = 10 TID = 0x00007FD508371000 NID = 0x55ae esperando la entrada del monitor [0x000007FD4F8684000] Java.lang.thread.state: Bloqueado (en el monitor de objetos) en org.apache.log4j.category.callappenders (category.java:201)- esperando bloquear <0x0000000000acf4d0c0> (a org.apache.log4j.logger) en org.apache.log4j.category.forcedlog (categoría.Java:388) AT org.apache.log4j.category.log (category.java:853) en org.apache.commons.logging.impl.log4jlogger.warn (log4jlogger.java:234) en com.tuan.core.common.lang.cache.remote.spymemcachedclient.get (spymemcachedclient.java:110)
ilustrar:
1) El estado de hilo está bloqueado, bloqueado. ¡Significa que el hilo espera a que el recurso se agote!
2) "Esperando bloquear <0x000000000000ACF4D0C0>" significa que el hilo está esperando para bloquear la dirección 0x0000000000ACF4D0C0 (se puede describir en inglés como: tratar de obtener 0x000000000000ACF4D0C0 LLOQUEO).
3) Busque la cadena 0x0000000000ACF4D0C0 en el registro de volcado y descubra que hay una gran cantidad de hilos que esperan para bloquear esta dirección. Si puede encontrar quién ha obtenido este bloqueo en el registro (como bloqueado <0x00000000ACF4D0C0>), puede seguir las pistas.
4) "Esperando la entrada del monitor" significa que este hilo ingresa al área crítica a través de la aplicación sincronizada (obj) {...}, ingresando así la cola de "Conjunto de entrada" en la Figura 1 a continuación. Sin embargo, el monitor correspondiente al OBJ es propiedad de otros hilos, por lo que este hilo espera en la cola de conjunto de entrada.
5) En la primera línea, "Conexión RMI TCP (267865) -172.16.5.25" es el nombre del hilo. TID se refiere a la identificación de hilo de Java. NID se refiere a la identificación del hilo nativo. Prio es prioridad del hilo. [0x00007FD4F8684000] es la dirección de inicio de la pila de subprocesos.
Ejemplo 2: Esperando en condición y Timed_waiting
"RMI TCP CONEXT (Idle)" Daemon Prio = 10 TID = 0x00007FD50834E800 nid = 0x56b2 Esperando en condición [0x000007FD4F1A59000] java.lang.thread.state: timed_waiting (estacionamiento) en sun.misc.unsafe.park (método nativo)- estacionamiento a la espera de espera <0x0000000000acd84de8> (un java.util.concurrent.synchronousqueue $ transferstack) en java.util.concurrent.locks.locksupport.parknanos (Locksupport.java:198) AT java.util.concurrent.synchronousqueue $ transferstack.awaitfulfill (synchronousqueue.java:424) en java.util.concurrent.synchronousqueue $ transferstack.transfer (synchronousqueue.Java:323) en java.util.concurrent.synchronousqueue.poll (synchronousqueue.java:874) en java.util.concurrent.threadpoolexecutor.getTask (threadpoolexecutor.java:945) AT java.util.concurrent.threadpoolexecutor $ trabajador.run (Threadpoolexecutor.java:907) en java.lang.thread.run (Thread.java:662)
ilustrar:
1) El Timed_Waiting en "Timed_waiting (estacionamiento)" se refiere al estado de espera, pero el tiempo se especifica aquí, y el estado de espera saldrá automáticamente después de alcanzar el tiempo especificado; Los estacionamientos se refieren al hilo que se suspende.
2) "Esperar en condición" debe combinarse con "estacionamiento para esperar <0x00000000acd84de8> (un java.util.concurrent.synchronousqueue $ transferstack)" en la pila. En primer lugar, este hilo definitivamente está esperando que una determinada condición se despierte. En segundo lugar, Synchronousqueue no es una cola, es solo un mecanismo para entregar información entre hilos. Cuando colocamos un elemento en Synchronousqueue, debe haber otro hilo esperando que se entregue la tarea, por lo que esta es la condición que está esperando este hilo.
3) No puedo ver nada más.
Ejemplo 3: en obejct.wait () y Timed_waiting
"RMI RenewClean- [172.16.5.19:28475]" Daemon prio = 10 tid = 0x00000000000041428800 nid = 0xb09 en object.wait () [0x00007f34f4f4bd0000] java.lang.thread.state: timed_waiting (en el monitor de objeto) en java.lang.woOt.wait.wait.wait.wait. Método)- esperando <0x00000000aa672478> (un java.lang.ref.referenceue $ bloqueo) en java.lang.ref.referenceue.remove (referencequeue.java:118)- bloqueado <0x0000000000aa672478> (a java.lang.ref.referencequeue Sun.rmi.transport.dgcclient $ Endpointentry $ RenewCleArtHread.run (dgcclient.java:516) en java.lang.thread.run (Thread.java:662)
ilustrar:
1) "Timed_waiting (en el monitor de objeto)" Para este ejemplo, es porque este hilo llama a java.lang.object.wait (tiempo de espera largo) y ingresa al estado de espera.
2) El estado de hilo de espera en "Wait Set" es "en Object.Wait ()". Cuando el hilo obtiene el monitor y ingresa a la sección crítica, si encuentra que el hilo continúa en ejecución, no se cumple, llama al método Wait () del objeto (generalmente el objeto sincronizado), abandona el monitor y entra en la cola "Wait Set". Solo cuando otros subprocesos llaman a notificar () o notifyAll () en el objeto, los subprocesos en la cola de "espera de espera" tienen la oportunidad de competir, pero solo un hilo obtiene el monitor del objeto y vuelve al estado en ejecución.
3) RMI RenewClean es parte de DGCClient. DGC se refiere a GC distribuido, es decir, recolección de basura distribuida.
4) Tenga en cuenta que está bloqueado primero <0x0000000AA672478> y luego espera <0x0000000AA672478>. La razón para bloquear primero y luego igualar el mismo objeto es ver su implementación de código a continuación:
Bloqueo de clase privada estática {}; bloqueo privado bloqueo = nuevo bloqueo (); Referencia pública <? extiende t> eliminar (tiempo de tiempo largo) {sincronizado (bloqueo) {referencia <? extiende t> r = realmentePoll (); if (r! = null) return r; para (;;) {Lock.Wait (Tiempo de espera); r = realmentePoll (); …}}Es decir, durante la ejecución del hilo, el monitor de este objeto se obtiene con sincronizado primero (correspondiente a bloqueado <0x0000000AA672478>); Cuando se ejecuta para bloquear. WAIT (Tiempo de espera);, el hilo abandona la propiedad del monitor y ingresa a la cola de "espera" (correspondiente a esperar <0x00000000AA672478>).
5) A juzgar por la información de la pila, se están limpiando las referencias remotas a objetos remotos. El contrato de arrendamiento referenciado ha llegado, y la recolección de basura distribuida se está limpiando uno por uno.
referencia:
Resuelve el problema del punto muerto de proceso a través del código de ejemplo de análisis JSTACK
Resumir
Lo anterior se trata de los escenarios de análisis y uso de la herramienta de análisis de volcado de hilo Java Jstack, espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!