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
.
Causa
Esses problemas podem ter muitas causas.
Uma causa possível é 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 ficar 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 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.
Clique 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 o pid do processo java para o qual você está gerando um despejo de heap.
ps -ef | grep java
ou jps -l
Ctrl+Shift+Esc
em seguida, vá para Exibir em seguida, vá para Selecionar colunas em seguida, vá para PID (Identificador do Processo) ou jps -l
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 o 1234
pela pid que você pesquisou na etapa anterior.
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 sua configuração de parâmetro max 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 é 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 Ferramentas de Monitoramento e Diagnóstico da IBM para Java - Memory Analyzer Versão 1.2 instalado no topo. 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 o ID do processo Java. Para obtê-lo, execute 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 o 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:
Referências
1 Guia de solução de problemas do Oracle Help Center para a VM HotSpot
2 Opções de depuração javas do Oracle.com