O JSTACK é usado para imprimir as informações da pilha Java de um determinado ID do processo Java ou o arquivo principal ou o serviço de depuração remota. Se estiver em uma máquina de 64 bits, você precisará especificar a opção "-j-d64". O uso do Windows Jstack suporta apenas os seguintes métodos:
jstack [-l] [f] pid
Se um programa Java travar para gerar um arquivo principal, a ferramenta JStack poderá ser usada para obter informações sobre a pilha Java e a pilha nativa do arquivo principal, para que você possa saber facilmente como o programa Java trava e onde o programa é problemático. Além disso, a ferramenta Jstack também pode ser anexada ao programa Java em execução e ver as informações sobre a pilha Java e a pilha nativa do programa Java que estava em execução naquele momento. Se o programa Java Running agora renderizar o estado de Hung, o JSTack é muito útil. Se o processo estiver em um estado morto de Hung, você poderá forçar a pilha a ser tocada com -f.
No arquivo de despejo, o status do thread que vale a pena prestar atenção é:
Deadlock, Deadlock (foco)
Executável
Esperando na condição (foco)
Esperando na entrada do monitor (foco)
Suspenso
Objeto esperando, object.wait () ou timed_waiting
Bloqueado, bloqueado (focado)
Pare, estacionado
Dei uma olhada em três cenários de outro blog:
Exemplo 1: Esperando para travar e bloqueado
"RMI TCP Connection (267865) -172.16.5.25" Daemon PRIO = 10 TID = 0x00007FD508371000 NID = 0x55AE Aguardando a entrada do monitor [0x000007FD4F8684000] org.apache.log4j.Category.callAppenders(Category.java:201)- waiting to lock <0x00000000acf4d0c0> (a org.apache.log4j.Logger)at org.apache.log4j.Category.forcedLog(Category.java:388) at org.apache.log4j.category.log (category.java:853) em org.apache.commons.logging.impl.log4jlogger.warn (log4jlogger.java:234) em com.tuan.core.common.lang.cache.remote.spymemcachedclient.get (spymcachedclient.java:110)
ilustrar:
1) O estado da rosca está bloqueado, bloqueado. Isso significa que o tópico aguarda o recurso para passar o tempo!
2) "Esperando para bloquear <0x000000ACF4D0C0>" significa que o thread está esperando para bloquear o endereço 0x000000ACF4D0C0 (pode ser descrito em inglês como: Tentando obter 0x0000000000ACF4D0C0 Lock).
3) Pesquise a string 0x000000ACF4D0C0 no log de despejo e descobriu que há um grande número de threads esperando para bloquear esse endereço. Se você puder encontrar quem obteve esse bloqueio no log (como bloqueado <0x00000000ACF4D0C0>), você pode seguir as pistas.
4) "Aguardar a entrada do monitor" significa que este thread entra na área crítica através do aplicativo sincronizado (OBJ) {...}, inserindo assim a fila "Conjunto de entrada" na Figura 1 abaixo. No entanto, o monitor correspondente ao OBJ é de propriedade de outros threads; portanto, esse thread aguarda na fila de conjuntos de entrada.
5) Na primeira linha, "RMI TCP Connection (267865) -172.16.5.25" é o nome do thread. Tid refere -se ao ID do tópico Java. NID refere -se ao ID do fio nativo. Prio é prioridade do tópico. [0x00007FD4F8684000] é o endereço de inicialização da pilha de threads.
Exemplo 2: Esperando na condição e timed_waiting
"RMI TCP Connection (IDLE)" Daemon Prio = 10 Tid = 0x00007FD50834E800 NID = 0x56b2 Esperando sob condição [0x000007fd4f1a59000] java.lang.thread.state: timed_waiting (estacionamento) em sun.misc.shpe.ung.thread.state: timed_waiting (estacionamento) em sun.misc.s <0x00000000ACD84DE8> (a java.util.concurrent.synchronsquosquee $ transferstack) em java.util.concurrent.locks.locksupport.parknanos (locksupport.java:198) java.util.concurrent.synchronsQueue $ transferstack.awaitfill (syncronsoSqueue.java:424) em java.util.concurrent.synchronsqueue $ transferstack.transfer (synchronsoSqueue.java:323) java.util.Concurrent.synchronsQueue.poll (syncronsoSqueue.java:874) em java.util.concurrent.threadpoolExecutor.gettask (threadpoolexecutor.java:945) em java.util.concurrent.threadpoolExecutor $ trabalhador.run (threadpoolexecutor.java:907) em java.lang.thread.run (thread.java:662)
ilustrar:
1) o timed_waiting em "timed_waiting (estacionamento)" refere -se ao estado de espera, mas o tempo é especificado aqui, e o estado de espera sairá automaticamente após o atendimento do tempo especificado; estacionamento refere -se à suspensão do fio.
2. Primeiro de tudo, este tópico está definitivamente esperando que uma certa condição se acorde. Em segundo lugar, o síncrono não é uma fila, é apenas um mecanismo para entregar informações entre os threads. Quando colocamos um elemento no síncrono, deve haver outro thread aguardando a entrega da tarefa, então essa é a condição que este thread está esperando.
3) Não consigo ver mais nada.
Exemplo 3: em obejct.wait () e timed_waiting
"RMI renewclean- [172.16.5.19:28475]" Daemon Prio = 10 Tid = 0x000000000041428800 nid = 0xb09 em object.wait () [0x00007f34f4bd00] Método)- Esperando em <0x00000000AA672478> (a java.lang.ref.referenceQueue $ bloqueio) em java.lang.ref.referencequee.remove (referencequeue.java:118)- bloqueado <0x000000aa672478> (a java:18) Sun.rmi.transport.dgcclient $ endpointentry $ renewcleanthread.run (dgcclient.java:516) em java.lang.thread.run (thread.java:662)
ilustrar:
1) "timed_waiting (no monitor de objeto)" para este exemplo, é porque este thread chama java.lang.object.wait (tempo limite de longo prazo) e entra no estado de espera.
2) O estado do thread em espera em "Wait Set" está "em object.wait ()". Quando o thread obtém o monitor e entra na seção crítica, se descobrir que o thread continua sendo executado não é atendido, ele chama o método Wait () do objeto (geralmente o objeto sincronizado), abandona o monitor e entra na fila "Wait Set". Somente quando outros threads chamam notify () ou notifyAll () no objeto, os threads na fila "Wait Set" têm a oportunidade de competir, mas apenas um thread recebe o monitor do objeto e retorna ao estado em execução.
3) RMI Renewclean faz parte do DGCClient. O DGC refere -se à GC distribuída, ou seja, coleta de lixo distribuída.
4) Observe que está bloqueado primeiro <0x0000000AA672478> e depois aguardando <0x0000000AA672478>. A razão para travar primeiro e depois igual ao mesmo objeto é ver sua implementação de código abaixo:
Classe privada estática bloqueio {}; bloqueio privado = new Lock (); referência pública <?? estende t> remover (tempo limite longo) {sincronizado (bloqueio) {reference <? estende t> r = realmentepoll (); if (r! = null) retorna r; para (;;) {Lock.wait (tempo limite); r = realmentepoll (); …}}Ou seja, durante a execução do encadeamento, o monitor desse objeto é obtido com o primeiro sincronizado (correspondente a bloqueado <0x0000000AA672478>); quando executado para bloquear.wait (tempo limite);, o thread abandona a propriedade do monitor e entra na fila "Wait Set" (correspondente a aguardar <0x00000000AA672478>).
5) A julgar pelas informações da pilha, referências remotas a objetos remotos estão sendo limpos. Chegou o arrendamento referenciado e a coleta de lixo distribuída está limpando uma a uma.
referência:
Resolva Problema de Deadlock de Processo através do Código de Exemplo de Análise JStack
Resumir
O exposto acima é sobre os cenários de análise e uso da ferramenta de análise Java Thread Dump Jstack, espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!