Como administrador de sistema, às vezes enfrento situações em que um programa se comporta de maneira anormal, sem criar erros ou criar mensagens de erro sem sentido.
No passado - antes da entrada do Java - havia duas contramedidas:
Se nada mais ajudar - RTFM ;-)
Se o 1. nem ajuda - rastreie as chamadas do sistema e veja o que está acontecendo
Eu normalmente uso strace -fpara esta tarefa com o Linux (outro sistema operacional possui ferramentas de rastreamento semelhantes). Agora, embora isso geralmente funcione bem para qualquer programa antiquado, o rastreamento fica muito confuso ao fazer o mesmo em um java . Existem tantas chamadas de sistema aparentemente sem relação com qualquer ação real, que é terrível procurar por esse despejo.
Existem maneiras melhores de fazer isso (se o código-fonte não estiver disponível)?
Como ckhan mencionou, jstacké ótimo porque fornece o rastreamento completo da pilha de todos os encadeamentos ativos na JVM. O mesmo pode ser obtido no stderr da JVM usando SIGQUIT.
Outra ferramenta útil é a jmapque pode obter um dump de heap do processo da JVM usando o PID do processo:
jmap -dump:file=/tmp/heap.hprof $PID
Esse dump de heap pode ser carregado em ferramentas como visualvm(que agora faz parte da instalação padrão do Oracle java sdk, denominada jvisualvm). Além disso, o VisualVM pode se conectar à JVM em execução e exibir informações sobre a JVM, incluindo gráficos do uso interno da CPU, contagens de encadeamentos e uso de heap - ótimo para rastrear vazamentos.
Outra ferramenta, jstatpode coletar estatísticas de coleta de lixo para a JVM durante um período semelhante à vmstat quando executada com um argumento numérico (por exemplo,vmstat 3 ).
Por fim, é possível usar um Java Agent para enviar a instrumentação a todos os métodos de todos os objetos no momento do carregamento. A biblioteca javassistpode ajudar a tornar isso muito fácil de fazer. Portanto, é possível adicionar seu próprio rastreio. A parte mais difícil disso seria encontrar uma maneira de obter saída de rastreio apenas quando você quisesse e não o tempo todo, o que provavelmente atrasaria a JVM para um rastreamento. Existe um programa chamado dtraceque funciona dessa maneira. Eu tentei, mas não foi muito bem sucedido. Observe que os agentes não podem instrumentar todas as classes porque os necessários para inicializar a JVM são carregados antes que o agente possa instrumentar, e é tarde demais para adicionar instrumentação a essas classes.
Minha sugestão - comece com o VisualVM e veja se isso lhe diz o que você precisa saber, pois ele pode mostrar os threads atuais e estatísticas importantes para a JVM.
A propósito, esta é uma pergunta impressionante; Espero que mais pessoas adicionem respostas com outras idéias. Quando perguntei às pessoas que trabalham com Java por muitos anos sobre rastreamento, elas me deram olhares em branco. Talvez eles simplesmente não conheçam a grandiosidade do traço.
ash
10
Da mesma forma, ao depurar programas que deram errado em um sistema Linux, você pode usar ferramentas semelhantes para depurar JVMs em execução no sistema.
Ferramenta # 1 - jvmtop
Semelhante top, você pode usar o jvmtop para ver quais classes estão fazendo dentro das JVMs em execução no seu sistema. Uma vez instalado, você o invoca assim:
$ jvmtop.sh
Sua saída possui um estilo semelhante para parecer com a ferramenta top:
JvmTop 0.8.0 alpha amd64 8 cpus, Linux 2.6.32-27, load avg 0.12
http://code.google.com/p/jvmtop
PID MAIN-CLASS HPCUR HPMAX NHCUR NHMAX CPU GC VM USERNAME #T DL
3370 rapperSimpleApp 165m 455m 109m 176m 0.12% 0.00% S6U37 web 21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager 11m 28m 23m 130m 0.00% 0.00% S6U37 web 31
19187 m.jvmtop.JvmTop 20m 3544m 13m 130m 0.93% 0.47% S6U37 web 20
16733 artup.Bootstrap 159m 455m 166m 304m 0.12% 0.00% S6U37 web 46
Ferramenta # 2 - jvmmonitor
Outra alternativa é usar o jvmmonitor . O JVM Monitor é um profiler Java integrado ao Eclipse para monitorar CPU, threads e uso de memória de aplicativos Java. Você pode usá-lo para encontrar automaticamente JVMs em execução no host local ou pode se conectar a JVMs remotas usando uma porta @ host.
Ferramenta # 3 - visualvm
visualvm provavelmente é "a ferramenta" a ser alcançada ao depurar problemas com a JVM. Seu conjunto de recursos é bastante profundo e você pode obter uma visão mais profunda das entranhas.
Perfile o desempenho do aplicativo ou analise a alocação de memória:
Considere jstack. Não é exatamente uma partida para strace, mais de umpstack -análogo, mas pelo menos lhe dará uma imagem de um instantâneo a tempo. Poderia amarrá-los para obter um rastro bruto, se necessário.
Se você estiver usando o RHEL OpenJDK (ou semelhante, o ponto é que não é o JDK do Oracle), você pode usar o SystemTap para isso.
Algumas sondas estão ativadas usando as opções de linha de comando java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Observe que a ativação dessas análises afetará significativamente o desempenho do programa.
Você também pode usar jstack()para obter a pilha Java do processo, mas só funcionará se você iniciar o SystemTap antes da JVM.
Observe que o SystemTap rastreará todos os métodos. Também não é possível obter argumentos do método. Outra opção é usar os próprios recursos de rastreio da JVM, que são chamados de JVMTI. Uma das implementações mais famosas da JVMTI é o BTrace .
É recomendável experimentar o Jackplay , que é uma ferramenta de rastreamento da JVM, permitindo rastrear a entrada e a saída do método sem alteração ou reimplantação do código.
Da mesma forma, ao depurar programas que deram errado em um sistema Linux, você pode usar ferramentas semelhantes para depurar JVMs em execução no sistema.
Ferramenta # 1 - jvmtop
Semelhante
top
, você pode usar o jvmtop para ver quais classes estão fazendo dentro das JVMs em execução no seu sistema. Uma vez instalado, você o invoca assim:Sua saída possui um estilo semelhante para parecer com a ferramenta
top
:Ferramenta # 2 - jvmmonitor
Outra alternativa é usar o jvmmonitor . O JVM Monitor é um profiler Java integrado ao Eclipse para monitorar CPU, threads e uso de memória de aplicativos Java. Você pode usá-lo para encontrar automaticamente JVMs em execução no host local ou pode se conectar a JVMs remotas usando uma porta @ host.
Ferramenta # 3 - visualvm
visualvm provavelmente é "a ferramenta" a ser alcançada ao depurar problemas com a JVM. Seu conjunto de recursos é bastante profundo e você pode obter uma visão mais profunda das entranhas.
Perfile o desempenho do aplicativo ou analise a alocação de memória:
Obter e exibir despejos de linha:
Referências
fonte
Considere
jstack
. Não é exatamente uma partida parastrace
, mais de umpstack
-análogo, mas pelo menos lhe dará uma imagem de um instantâneo a tempo. Poderia amarrá-los para obter um rastro bruto, se necessário.Consulte também as sugestões deste artigo do SO: /programming/1025681/call-trace-in-java
fonte
Se você estiver usando o RHEL OpenJDK (ou semelhante, o ponto é que não é o JDK do Oracle), você pode usar o SystemTap para isso.
Algumas sondas estão ativadas usando as opções de linha de comando java
-XX:+DTraceMethodProbes
,-XX:+DTraceAllocProbes
,-XX:+DTraceMonitorProbes
. Observe que a ativação dessas análises afetará significativamente o desempenho do programa.Aqui está um exemplo de script SystemTap:
Você também pode usar
jstack()
para obter a pilha Java do processo, mas só funcionará se você iniciar o SystemTap antes da JVM.Observe que o SystemTap rastreará todos os métodos. Também não é possível obter argumentos do método. Outra opção é usar os próprios recursos de rastreio da JVM, que são chamados de JVMTI. Uma das implementações mais famosas da JVMTI é o BTrace .
fonte
É recomendável experimentar o Jackplay , que é uma ferramenta de rastreamento da JVM, permitindo rastrear a entrada e a saída do método sem alteração ou reimplantação do código.
fonte