Sintomas
Se você enfrentar as seguintes condições, o problema pode ser devido a sessões não fechadas no CRX:
- O sistema fica cada vez mais lento
- De tempos em tempos, o sistema fica sem memória (após algumas horas, dias ou semanas - dependendo da gravidade)
- Versão mais antiga do CRX: você tem um monte de entradas "CacheManager: resizeAll" no arquivo de log (o número por trás de size=... é o número de caches; cada sessão abre alguns caches)
Causa
Se um aplicativo abrir o CRXSessions explicitamente, é de responsabilidade do desenvolvedor garantir o encerramento adequado dessas sessões. Caso contrário, essas sessões não estarão sujeitas à coleta de lixo e, portanto, permanecerão na memória, causando os sintomas listados acima. Cada CRXSession cria e mantém seu próprio conjunto de caches, o que é adicionado ao consumo geral de recursos.
Análise
Para identificar um problema real com sessões não fechadas, execute os seguintes comandos para determinar o número geral de CRXSessions atuais mantidas na memória:
jmap -histo:live <pid> | grep CRXSessionImpl
A segunda coluna da saída é a contagem de instâncias, o que significa que muitas sessões não estão fechadas (e, na verdade, residem na memória). Se esse número for significativamente maior que 100, então há um problema com o CRXSessions em seu aplicativo.
Para consultar quantos objetos CRXSession estão retidos na memória, incluindo aqueles que estão esperando para serem coletados como lixo, execute o comando abaixo:
- jmap -histo <pid> | grep CRXSessionImpl
Como no comando anterior, a segunda coluna é a contagem de instâncias. Isso informa quantos objetos de sessão estão na memória que estão ativos ou que ainda não foram coletados como lixo. Esse número, em comparação com o anterior, pode informar se você está abrindo e fechando muitas sessões CRX em seu aplicativo.
Se você estiver executando o CRX2.3 ou CQ5.5, poderá forçar uma coleta de lixo completa do jvm indo a http://<host>:<port>/system/console/memoryusage e clicando no botão "Executar coleta de lixo". Depois de fazer isso, você pode executar o comando acima novamente algumas vezes para ver a rapidez com que o número de objetos de sessão aumenta. Isso lhe dará uma ideia se seu aplicativo estiver abrindo e fechando muitas sessões ou se você precisar ajustar suas configurações de gc. Geralmente, se isso for realmente um problema, você notará grandes pausas de coleta de lixo da jvm e desempenho lento durante as operações de salvamento no repositório.
Observação: O aplicativo de linha de comando jmap é fornecido com o java JDK e pode ser encontrado no diretório home bin do jdk.
Solução
Para resolver esse problema, é necessária uma análise mais aprofundada para descobrir quem realmente abre CRXSessions e, mais importante, não as fecha. A partir do 1.4.1, o CRX vem com um modo de depuração integrado que permite reconstituir o código do defeito. O que esse modo de depuração faz basicamente é descarregar um rastreamento de pilha completo no arquivo de log padrão sempre que uma sessão CRXSession for aberta. Ele também registra uma entrada sempre que uma CRXSession é fechada novamente.
Para ativar o modo de depuração da sessão, inclua o seguinte parâmetro da JVM ao iniciar o CRX:
-Dcrx.debug.sessions=true
Observação: Dependendo do uso do sistema, o arquivo de log pode crescer bem rápido.
Ao usar o início rápido, a opção -nofork precisa ser usada para garantir que a propriedade do sistema seja usada.
Assim que você reunir rastreamentos de pilha suficiente (é mais fácil analisar o problema se houver pelo menos 1000 sessões não fechadas), pare a instância e remova o parâmetro JVM novamente. O arquivo de log (log de saída do sistema ou error.log, dependendo da versão usada) conterá as seguintes mensagens, além de rastreamentos de pilha:
- com.day.crx.core.CRXSessionImpl session# 193 opened
Em seguida, execute o arquivo jar anexado com o seguinte comando:
java -jar session_analyzer.jar <log_file> | sort > output.txt
Isto irá gerar um novo arquivo output.txt
que contém o rastreamento de pilha de sessões não fechadas, classificadas pelo conteúdo de rastreamento de pilha. Cada rastreamento de pilha é uma linha e 'compactado' um pouco (os prefixos repetidos são removidos). O ID da sessão está no final da linha.
Exemplo:
com.day.crx.j2ee.JCRExplorerServlet.login(JCRExplorerServlet.java:521) ResourceServlet.spoolResource(ResourceServlet.java:148) java.lang.Thread.run(Thread.java:595): session# 10023
Este exemplo significa que a sessão #10023 não foi fechada e o rastreamento de pilha incluiu as linhas fornecidas quando a sessão foi aberta.
Com base nessa saída, você deve conseguir localizar o local do código do defeito e corrigir o problema. Caso você tenha encontrado um defeito em nosso código principal do produto, por favor, envie um ticket Daycare junto com as informações coletadas acima.
Aplica-se a
CRX 1.3.x (peça um patch se você precisar analisar o problema)
CRX 1.4.x (para 1.4.0 você precisa instalar o hotfix no anexo)
CRX 2.x
Download
Download
Download