Eu tenho um aplicativo Java que eu executo em um console que, por sua vez, executa outro processo Java. Eu quero obter um despejo de thread / heap desse processo filho.
No Unix, eu poderia fazer isso, kill -3 <pid>
mas no Windows AFAIK a única maneira de obter um despejo de threads é Ctrl-Break no console. Mas isso só me dá o despejo do processo pai, não o filho.
Existe outra maneira de obter esse despejo de pilha?
java
jvm
heap-dump
thread-dump
Kasun Siyambalapitiya
fonte
fonte
Respostas:
Você pode usar
jmap
para obter um despejo de qualquer processo em execução, supondo que você saiba opid
.Use o Gerenciador de tarefas ou o Monitor de recursos para obter o
pid
. Entãopara obter a pilha para esse processo.
fonte
Você está confundindo dois despejos java diferentes.
kill -3
gera um despejo de encadeamento, não um despejo de heap.Para executar um despejo de encadeamento no Windows, CTRL+ BREAKse sua JVM for o processo em primeiro plano, é a maneira mais simples. Se você possui um shell do tipo unix no Windows, como Cygwin ou MobaXterm, pode usar
kill -3 {pid}
lo como no Unix.Para fazer um despejo de encadeamento no Unix, CTRL+ Cse sua JVM for o processo em primeiro plano ou
kill -3 {pid}
funcionará desde que você obtenha o PID correto para a JVM.Em qualquer plataforma, o Java vem com vários utilitários que podem ajudar. Para despejos de linha,
jstack {pid}
é sua melhor aposta. http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.htmlApenas para finalizar a pergunta de despejo: despejos de pilha não são comumente usados porque são difíceis de interpretar. Mas, eles têm muitas informações úteis, se você souber onde / como olhar para eles. O uso mais comum é localizar vazamentos de memória. É uma boa prática definir
-D
na linha de comando java para que o dump do heap seja gerado automaticamente em um OutOfMemoryError.-XX:+HeapDumpOnOutOfMemoryError
Porém, você também pode acionar manualmente um dump do heap. A maneira mais comum é usar o utilitário javajmap
.NOTA: este utilitário não está disponível em todas as plataformas. A partir do JDK 1.6,
jmap
está disponível no Windows.Um exemplo de linha de comando seria algo como
A saída "myheap.bin" não é legível por humanos (para a maioria de nós) e você precisará de uma ferramenta para analisá-la. Minha preferência é MAT. http://www.eclipse.org/mat/
fonte
Eu acho que a melhor maneira de criar arquivo .hprof no processo Linux é com o comando jmap . Por exemplo:
jmap -dump:format=b,file=filename.hprof {PID}
fonte
Além de usar o jconsole / visualvm mencionado, você pode usar
jstack -l <vm-id>
em outra janela da linha de comandos e capturar essa saída.O <vm-id> pode ser encontrado usando o gerenciador de tarefas (é o ID do processo no Windows e no Unix) ou usando
jps
.Ambos
jstack
ejps
estão incluídos no Sun JDK versão 6 e superior.fonte
Eu recomendo o Java VisualVM distribuído com o JDK (jvisualvm.exe). Ele pode se conectar dinamicamente e acessar os threads e a pilha. Eu achei inestimável para alguns problemas.
fonte
Se você estiver no server-jre 8 e acima, poderá usar o seguinte:
fonte
Experimente uma das opções abaixo.
Para JVM de 32 bits:
Para JVM de 64 bits (citando explicitamente):
Para a JVM de 64 bits com o algoritmo G1GC nos parâmetros da VM (apenas o heap de objetos ativos é gerado com o algoritmo G1GC):
Pergunta SE relacionada: Erro de despejo de heap Java com o comando jmap: EOF prematuro
Dê uma olhada em várias opções
jmap
deste artigofonte
Se você desejar um heapdump com falta de memória, poderá iniciar o Java com a opção
-XX:-HeapDumpOnOutOfMemoryError
cf Página de referência de Opções da JVM
fonte
Você pode executar
jconsole
(incluído no SDK do Java 6) e conectar-se ao seu aplicativo Java. Ele mostrará todos os Threads em execução e seu rastreamento de pilha.fonte
Você pode enviar o
kill -3 <pid>
da Cygwin. Você precisa usar asps
opções do Cygwin para encontrar os processos do Windows, basta enviar o sinal para esse processo.fonte
Você precisa redirecionar a saída do segundo executável java para algum arquivo. Em seguida, use o SendSignal para enviar "-3" ao seu segundo processo.
fonte
Se você estiver usando o JDK 1.6 ou superior, poderá usar
jmap
comando para fazer um heap Dump de um processo Java, a condição é que você deve conhecer ProcessID.Se você estiver no Windows Machine, poderá usar o Gerenciador de tarefas para obter o PID. Para máquinas Linux, você pode usar variedades de comando como
ps -A | grep java
ounetstat -tupln | grep java
outop | grep java
, depende do seu aplicativo.Em seguida, você pode usar o comando como
jmap -dump:format=b,file=sample_heap_dump.hprof 1234
onde 1234 é PID.Existem diversas ferramentas disponíveis para interpretar o arquivo hprof. Vou recomendar a ferramenta visualvm da Oracle, que é simples de usar.
fonte
Se você não puder (ou não quiser) usar o console / terminal por algum motivo, existe uma solução alternativa. Você pode fazer com que o aplicativo Java imprima o despejo de encadeamento para você. O código que coleta o rastreamento de pilha é bastante simples e pode ser anexado a um botão ou interface da web.
Este método retornará uma string parecida com esta:
Para os interessados em uma versão Java 8 com fluxos, o código é ainda mais compacto:
Você pode facilmente testar esse código com:
fonte
O script a seguir usa o PsExec para conectar-se a outra sessão do Windows, para que funcione mesmo quando conectado pelo Serviço de Área de Trabalho Remota.
Escrevi um pequeno script em lote para o Java 8 (usando
PsExec
ejcmd
) chamadojvmdump.bat
, que despeja os encadeamentos, heap, propriedades do sistema e args da JVM.Ele deve ser executado na mesma sessão do Windows do usuário que iniciou a JVM; portanto, se você se conectar pela Área de Trabalho Remota, poderá ser necessário iniciar um prompt de comando
Session 0
e executá-lo a partir daí. por exemploIsso solicitará que você (clique no ícone da barra de tarefas na parte inferior)
View the message
da sessão interativa, que o levará ao novo console na outra sessão a partir da qual você pode executar ojvmdump.bat
script.fonte
Como obter a identificação do processo do aplicativo java?
Execute o comando 'jcmd' para obter a identificação do processo de aplicativos java.
Como obter o despejo de threads?
jcmd PID Thread.print> thread.dump
Link de referência
Você pode até usar o jstack para obter o dump de threads (jstack PID> thread.dump). Link de referência
Como obter o heap dump?
Use a ferramenta jmap para obter o heap dump. jmap -F -dump: ativo, formato = b, arquivo = heap.bin PID
PID significa ID do processo do aplicativo. Link de referência
fonte
Talvez jcmd ?
O utilitário Jcmd é usado para enviar solicitações de comando de diagnóstico para a JVM, onde essas solicitações são úteis para controlar o Java Flight Recordings, solucionar problemas e diagnosticar JVM e aplicativos Java.
A ferramenta jcmd foi introduzida no Java 7 da Oracle e é particularmente útil na solução de problemas com aplicativos JVM, usando-a para identificar IDs de processos Java (semelhante ao jps), adquirindo dumps de pilha (semelhante ao jmap), adquirindo dumps de segmento (semelhante ao jstack ), visualizando características da máquina virtual, como propriedades do sistema e sinalizadores de linha de comando (semelhante ao jinfo) e adquirindo estatísticas de coleta de lixo (semelhante ao jstat). A ferramenta jcmd foi chamada "um canivete suíço para investigar e resolver problemas com seu aplicativo JVM" e uma "jóia escondida".
Aqui está o processo que você precisará usar para chamar
jcmd
:jcmd <pid> GC.heap_dump <file-path>
Confira para obter mais informações sobre como fazer o heap dump do Java .
fonte
Acompanhamento do Visualvm:
Se você "não conseguir se conectar" à sua JVM em execução a partir do jvisualvm porque não a iniciou com os argumentos corretos da JVM (e está na caixa remota), execute
jstatd
na caixa remota e, assumindo que você possui uma conexão direta, inclua como um "host remoto" no visualvm, clique duas vezes no nome do host e todas as outras JVMs nessa caixa aparecerão magicamente no visualvm.Se você não tiver "conexão direta" com as portas nessa caixa, também poderá fazer isso por meio de um proxy .
Depois de ver o processo desejado, faça uma busca detalhada no jvisualvm e use a guia monitor -> botão "heapdump".
fonte
Abaixo, o código java é usado para obter o Heap Dump de um processo Java, fornecendo PID. O programa usa a conexão JMX remota para despejar heap. Pode ser útil para alguém.
}
fonte
Para fazer o despejo de encadeamento / despejo de heap de um processo java filho no Windows, é necessário identificar o ID do processo filho como primeira etapa.
Emitindo o comando: jps você poderá obter todos os IDs de processos java que estão sendo executados na sua máquina Windows. Nessa lista, você precisa selecionar o ID do processo filho. Depois de ter o ID do processo filho, existem várias opções para capturar despejo de encadeamentos e despejos de heap.
Capturando Despejos de Thread:
Existem 8 opções para capturar despejos de encadeamento:
Detalhes sobre cada opção podem ser encontrados neste artigo . Depois de capturar despejos de encadeamento, você pode usar ferramentas como fastThread , o Samuraito analisa despejos de encadeamento.
Capturando despejos de pilha:
Existem 7 opções para capturar despejos de heap:
jmap
-XX: + HeapDumpOnOutOfMemoryError
jcmd
JVisualVM
JMX
Abordagem programática
Consoles administrativos
Detalhes sobre cada opção podem ser encontrados neste artigo . Depois de capturar o despejo de heap, você pode usar ferramentas como a ferramenta Eclipse Memory Analysis , HeapHero para analisar os despejos de heap capturados.
fonte
Em um Oracle JDK, temos um comando chamado jmap (disponível na pasta bin do Java Home). o uso do comando é o seguinte
Exemplo: jmap -dump: live, formato = b, arquivo = heap.bin (pid)
fonte