Como rastrear um programa java?

22

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 chegada do java - havia duas contra-medidas:

  1. Se nada mais ajudar - RTFM; -)
  2. Se até mesmo 1. não ajudar - rastreie as chamadas do sistema e veja o que está acontecendo

Eu costumo usar strace -f para essa tarefa com o Linux (outros sistemas operacionais têm ferramentas de rastreamento semelhantes). Agora, enquanto isso geralmente funciona bem para qualquer programa antigo, o rastreamento fica muito confuso ao fazer o mesmo em um processo java . Existem tantas chamadas de sistema aparentemente não relacionadas a qualquer ação real, que é terrível procurar em um depósito desse tipo.

Existem maneiras melhores de fazer isso (se o código-fonte não estiver disponível)?

    
por Nils 27.11.2012 / 23:10

5 respostas

14

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 o SIGQUIT.

Outra ferramenta útil é jmap , que pode capturar 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, chamada jvisualvm). Além disso, o VisualVM pode se conectar à JVM em execução e exibir informações sobre a JVM, incluindo a exibição de gráficos de uso interno da CPU, contagens de encadeamentos e uso de heap - ótimo para rastrear vazamentos.

Outra ferramenta, jstat , pode coletar estatísticas de coleta de lixo para a JVM por um período de tempo muito parecido com o vmstat quando executado com um argumento numérico (por exemplo, vmstat 3 ).

Finalmente, é possível usar um agente Java para enviar instrumentação em todos os métodos de todos os objetos no momento da carga. A biblioteca javassist pode ajudar a tornar isso muito fácil de fazer. Então, é possível adicionar seu próprio rastreamento. A parte difícil com isso seria encontrar uma maneira de obter saída de rastreio somente quando você desejasse e não o tempo todo, o que provavelmente atrasaria o rastreamento da JVM. Existe um programa chamado dtrace que funciona de uma maneira como essa. Eu tentei, mas não foi muito bem sucedido. Observe que os agentes não podem instrumentar todas as classes porque as necessárias para autoinicializar a JVM são carregadas antes que o agente possa instrumentar e, então, é muito tarde para incluir instrumentação nessas classes.

My Suggestion - comece com o VisualVM e veja se isso indica o que você precisa saber, pois ele pode mostrar os threads atuais e as estatísticas importantes da JVM.

    
por 28.08.2013 / 06:37
9

Da mesma forma, ao depurar programas que falharam em um sistema Linux, você pode usar ferramentas semelhantes para depurar as JVMs em execução em seu sistema.

Ferramenta 1 - jvmtop

Semelhante a top , você pode usar o jvmtop para ver quais classes estão executando nas JVMs em execução no seu sistema. Uma vez instalado, invoque-o assim:

$ jvmtop.sh

Sua saída tem o mesmo estilo para se 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 o uso de CPU, encadeamentos e memória de aplicativos Java. Você pode usá-lo para localizar automaticamente JVMs em execução no host local ou pode se conectar a JVMs remotas usando uma porta @ host.

Ferramenta3-visualvm

visualvm é provavelmente a ferramenta a ser usada para depurar problemas com a JVM. Seu conjunto de recursos é bastante profundo e você pode ter uma visão muito profunda das entranhas.

Perfile o desempenho do aplicativo ou analise a alocação de memória:

Captureeexibaosdumpsdesegmento:

Referências

por 29.08.2013 / 06:02
4

Considere jstack . Não é exatamente uma correspondência para strace , mais de um pstack -análogo, mas pelo menos fornecerá uma foto de um instantâneo no tempo. Poderia string'em juntos para obter um rastreio bruto, se necessário.

Veja também as sugestões neste artigo da SO: link

    
por 28.11.2012 / 03:39
1

Se você estiver usando o RHEL OpenJDK (ou semelhante, o ponto é que não é o JDK da Oracle), você pode usar SystemTap para naquela.

Alguns testes são ativados usando as opções de linha de comando java -XX:+DTraceMethodProbes , -XX:+DTraceAllocProbes , -XX:+DTraceMonitorProbes . Observe que habilitar esses probes afetará significativamente o desempenho do programa.

Aqui está o exemplo do script SystemTap:

#!/usr/bin/stap

probe hotspot.class_loaded {
    printf("%12s [???] %s\n", name, class);
}

probe hotspot.method_entry, 
      hotspot.method_return {
    printf("%12s [%3d] %s.%s\n", name, thread_id, class, method);
}

probe hotspot.thread_start, 
      hotspot.thread_stop {
    printf("%12s [%3d] %s\n", name, id, thread_name);
}

probe hotspot.monitor_contended_enter, 
      hotspot.monitor_contended_exit {
    printf("%12s [%3d] %s\n", name, thread_id, class);
}

Você também pode usar jstack() para obter a pilha Java do processo, mas ela só funcionará se você iniciar o SystemTap antes da JVM.

Note que o SystemTap irá rastrear o método every . Também não é capaz de obter argumentos do método. Outra opção é usar os recursos de rastreamento próprios da JVM, chamados de JVMTI. Uma das implementações mais famosas da JVMTI é o BTrace .

    
por 25.05.2015 / 16:05
0

Você é aconselhado a testar o Jackplay , que é uma ferramenta de rastreamento da JVM que permite rastrear a entrada do método e sai sem alteração de código ou redistribuição.

    
por 12.09.2016 / 14:08