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.
java
oom
outofmemoryerror
dump
karlcyr
fonte
fonte
Respostas:
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 .fonte
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.
fonte
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.
fonte
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.
fonte
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.
fonte