Como usar o Java Heap Dumps de maneira confiável?

9

Minha equipe está enfrentando dificuldades ao tentar obter bons despejos de heap acionados por OutOfMemoryErrors. Por motivos específicos, atualmente estamos fazendo os dumps com o jmap chamado de um script bash, em vez de usar o sinalizador HeapDumpOnOutOfMemoryError. Estamos usando uma JVM 1.6 de 64 bits e um tamanho de heap em torno de 3 GB. Nossos despejos de heap falham 90% do tempo (estimativa de estimativa).

Existe algo que possamos fazer para melhorar nossas chances de obter um despejo de heap limpo que possamos usar para solucionar problemas de memória? Eu li que o jmap tinha grandes problemas no Java 1.4, mas que esses problemas deveriam ser abordados principalmente agora.

karlcyr
fonte
4
Eu nomeio esta pergunta como "o som mais repugnante e sem querer".
Phoebus
1
Ah, eu pensei em fazer isso parecer intencionalmente nojento, mas sou novo aqui e não tinha certeza de como a comunidade aceitaria isso :).
22610 Karlcyr

Respostas:

7

Qual é o seu sistema operacional? (Não consigo adicionar comentários).

Para o Solaris, obtemos melhores resultados primeiro forçando um core dump ( gcore <pid>) e depois anexando o jmap ao arquivo de core dump ( jmap -heap:format=b <path to java bin> <path to core>)

gcoreé um utilitário * nix para gerar uma imagem de um programa em execução. Veja o link .

fglez
fonte
tentei com gdb no linux e funciona muito bem.
Christian
qual JDK tem "gcore"? mina, Sun 32 bits jdk para linux 1.6.0.20 não tem isso.
djangofan
Editado com esclarecimentos gcore.
fglez
2

temos um JSP que consulta ManagementFactory.getThreadMXBean () e produz um relatório. Pode não ser útil quando o aplicativo falha, mas se você pesquisar a cada minuto, você terá uma idéia do que está acontecendo.

Mais informações aqui.

Rytis
fonte
2

você pode monitorar seu aplicativo via jmx de fora. quando você conhece algumas métricas que indicam uma próxima OutOfMemory, você pode disparar uma execução jmap antes que a exceção seja lançada.

cristão
fonte
Obrigado Christian- é mais provável que o jmap seja confiável antes que o erro seja gerado?
22810 Karlcyr
O jmap ainda precisará de algum tempo para obter um despejo de pilha. mas você obterá um heapdump completo desde que o seu jvm / tomcat seja o principal responsável.
Christian
Eu acho que a ferramenta mais limpa e fácil de fazer isso é "Visual VM". Pode estar fora do escopo, mas criar um plug-in personalizado para o VisualVM que detecte a condição e faça o despejo automático no VisualVm seria um IMHO incrível.
precisa saber é o seguinte
2

Obrigado a todos por suas sugestões.

O que acabamos fazendo é escrever um script para monitorar ativamente os logs de coleta de lixo. Em nossa experiência, os GCs completos consecutivos quase sempre precedem um OOM, portanto, nosso script detecta esse evento, remove graciosamente o servidor do pool de balanceamento de carga e força o despejo de heap. Isso aumentou muito nossa eficácia.

karlcyr
fonte
2

Esta é uma pergunta bastante antiga, mas vou responder com a esperança de que alguém possa achar isso útil.

O jmap possui uma opção -F (force). Isso provou não funcionar tão bem no passado para mim. Se você deseja usar a opção -F, recomendo que você também especifique o diretório java.io.tmp como parte do comando jmap. Houve um problema na JVM versão 1.6.22 em que o utilitário jmap não funcionava corretamente devido a uma configuração de diretório temporário.

Você também pode tentar fazer um dump principal via gdb. Depois de ter o núcleo, o jmap pode converter o núcleo em um dump de heap.

Nick Hristov
fonte