Analisar problemas de memória
Saiba como identificar a causa de problemas de memória do aplicativo Java. Você pode gerar um despejo de heap automática e manualmente, além de um histograma de heap, para identificar a causa.
Descrição description
Ambiente
Experience Manager
Problema/Sintomas
O aplicativo JAVA é executado mais lentamente e, por fim, fica sem memória ou você vê um erro nos logs ou na saída do console OutOfMemoryError: Java heap space
ou OutOfMemoryError: gc overhead limit exceeded
.
Resolução resolution
Causa
Esses problemas podem ter muitas causas.
Uma possível causa é que o aplicativo java, no nosso caso o CRX/CQ, foi iniciado a partir da linha de comando com as configurações padrão de memória heap do Java. Isso significa que o parâmetro jvm -Xmx
não foi especificado. O CRX ou CQ precisa de pelo menos 256 MB de heap alocados para serem executados. Se esse for o problema, iniciando a partir da linha de comando, verifique se as configurações da memória heap estão definidas. Exemplo:
java -Xmx512m -jar *.jar
Se não for o caso, seu aplicativo pode estar retendo muitos objetos sem liberá-los para a coleta de lixo. Isso é chamado de vazamento de memória. Clique aqui para obter mais informações. Consulte a seção abaixo para ver como analisar problemas de memória em aplicativos java.
Criar despejo de heap:
Gerar um despejo de heap automaticamente
Para criar automaticamente um despejo de heap ao ficar sem memória, você pode adicionar o parâmetro jvm -XX:+HeapDumpOnOutOfMemoryError
para gerar um despejo de heap automaticamente quando o aplicativo lança um OutOfMemoryError. Por exemplo,
java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar
Isso gera um arquivo de despejo de heap (java_...hprof
) no diretório de trabalho do processo sempre que o processo java fica sem memória. O processo pode continuar a ser executado depois que o despejo de heap foi gerado. Geralmente, um arquivo de despejo de heap é suficiente para analisar o problema.
Observação: se estiver usando script crx-quickstart/server/start
para iniciar sua instância do CRX, você pode adicionar -XX:+HeapDumpOnOutOfMemoryError
para a variável CQ_JVM_OPTS
(verifique se a variável também não está comentada). Por exemplo:
CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'
Depois de adicionar esse parâmetro e reiniciar a instância do CRX, verifique se a nova opção jvm está definida. Executar o ps -ef | grep java
na linha de comando. Em seguida, verifique se você vê -XX:+HeapDumpOnOutOfMemoryError
como parâmetro do processo java do CRX.
Se você precisar especificar um diretório diferente para gerar o despejo de heap devido a restrições de espaço em disco, poderá adicionar o parâmetro -XX:HeapDumpPath=/path/to/generate/heapdump
para informar ao jvm onde colocar o arquivo.
Consulte aqui para obter uma referência de parâmetros jvm relacionados à depuração.
Gerar um despejo de heap manualmente
Sun/Oracle JVM
Para gerar manualmente um despejo de heap, execute este comando (jmap e jps podem ser encontrados na pasta bin
do seu diretório inicial jdk):
-
procure a pid do processo java para a qual você está gerando um despejo de heap.
- No Unix ou Linux isso pode ser feito com
ps -ef | grep java
oujps -l
- No Windows, isso pode ser feito abrindo o gerenciador de tarefas. Pressione
Ctrl+Shift+Esc
e vá para Exibir e, em seguida, vá para Selecionar Colunas e vá para PID (Identificador do Processo) oujps -l
- No Unix ou Linux isso pode ser feito com
-
Execute o comando jmap abaixo, substitua
/path/to/generate/heapdumpfile.hprof
pelo local em que você deseja gerar o arquivo de despejo de heap e substitua o1234
pela pid que você pesquisou na etapa anterior.code language-none jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
IBM JVM
Primeiro, você terá que alterar as configurações padrão da JVM em relação aos agentes de despejo para gerar os despejos corretos no sinal do usuário. Há vários tipos de despejos, mas você geralmente precisa do despejo do sistema completo para executar uma análise completa da memória. Adicione os seguintes argumentos:
Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user
Esse evento de "usuário" acontece quando a JVM recebe o sinal SIGQUIT (Linux, AIX®, z/OS® e i5/OS™) ou SIGBREAK (Windows) do sistema operacional.
Para obter mais informações, consulte a documentação do fornecedor aqui.
Aviso: os arquivos de despejo de heap são grandes e podem ter até o mesmo tamanho no disco que a configuração máxima do parâmetro heap -Xmx jvm. Verifique se há espaço em disco suficiente alocado para o diretório onde o arquivo de despejo é gerado.
Analisar despejo de heap
Uma boa ferramenta para analisar despejos de heap é o EclipseMAT (Eclipse Memory Analyzer).
Esta ferramenta não pode analisar dumps gerados pelo IBM JVM. Para eles, existem várias possibilidades. O IBM HeapAnalyzer funcionará bem para os despejos de heap no formato PHD ou clássico.
Para obter uma análise completa do despejo do sistema, use o Workbench do Assistente de Suporte da IBM, com as Ferramentas de Monitoramento e Diagnóstico da IBM para Java - Analisador de Memória instaladas. O histograma de heap é uma medida simples do número de objetos ativos e da memória usada por classe Java. Infelizmente, dependendo da instalação do Java, as ferramentas necessárias podem não estar disponíveis ou nem sempre funcionar. Para criar um histograma de heap, primeiro é necessário a ID do processo Java. Para obtê-lo, execute o ps or (if available), run:
Histograma de Heap
O histograma de heap é uma medida simples do número de objetos ativos e da memória usada por classe Java. Infelizmente, dependendo da instalação do Java, as ferramentas necessárias podem não estar disponíveis ou nem sempre funcionar. Para criar um histograma de heap, primeiro é necessário a ID do processo Java. Para obtê-la, execute ps
ou (se disponível), execute:
jps -l
Essa ferramenta Java obtém as IDs do processo de todos os processos Java em execução. Exemplo:
327
3332 sun.tools.jps.Jps
3313 crx-quickstart-....jar
Agora execute o seguinte comando:
jmap -histo 3313
A lista é classificada pela memória total necessária (superficial: excluindo objetos referenciados). As primeiras 20 linhas da saída são as mais interessantes. Exemplo de saída:
JVM version is 1.5.0_20-141
Iterating over heap. This may take a while...
Warning: skipping invalid TLAB for thread t@62211
Warning: skipping invalid TLAB for thread t@62467
...
SizeCountClass description
-------------------------------------------------------
1059290412916byte`[` `]`
1028584075255* ConstMethodKlass
628317658388char`[` `]`
604230414928int`[` `]`
4995752116201* SymbolKlass
422089675255* MethodKlass
41965126969* ConstantPoolKlass
29285606969* InstanceKlassKlass
26310086066* ConstantPoolCacheKlass
2395872149742org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId
14760087003java.util.HashMap$Entry`[` `]`
139612858172java.lang.String
107023244593java.util.HashMap$Entry
75398410036short`[` `]`
73546454org.apache.jackrabbit.core.query.lucene.DocId`[` `]`
7201927502java.lang.Class
64070413348com.day.crx.persistence.tar.index.IndexEntry
...
Informações adicionais
Para ajudar a analisar o problema, também precisamos saber as seguintes informações:
- Versão do CRX ou CQ, incluindo uma lista de todos os números de versão de hotfixes instalados.
- Sistema operacional, fornecedor de JVM e versão.
Referências
[
1]
Guia de Solução de Problemas da Central de Ajuda do Oracle >
para a VM HotSpot[
2]
Oracle.com >
javas >
DebuggingOptions