Tirar despejos de thread de uma JVM

Última atualização em 2023-10-30

Descrição

Ambiente

Experience Manager

Problema/Sintomas

Como remover despejos de thread de uma JVM no Linux, UNIX ou Windows?

Um despejo de thread é uma lista de todas as threads Java atualmente ativas em uma Java Virtual Machine (JVM).

Há várias maneiras de retirar despejos de thread de uma JVM. É altamente recomendável usar mais de 1 despejo de thread. Uma prática recomendada é realizar 10 despejos de thread em um intervalo regular (por exemplo, um despejo de thread a cada dez segundos).

Resolução

Etapa 1: Obtenha o PID do seu processo Java

A primeira informação que você precisará para obter um despejo de thread é o PID do processo Java.

O JDK do Java vem com o comando jps, que lista todas as IDs do processo Java. Você pode executar esse comando da seguinte maneira:

jps -l 70660 sun.tools.jps.Jps 70305

Nota: No Linux e no UNIX, talvez seja necessário executar esse comando como sudo -u usuário jps -l, onde "usuário" é o nome de usuário do usuário com o qual o processo Java está sendo executado.

Se isso não funcionar ou ainda não for possível encontrar o processo Java (caminho não definido, JDK não instalado ou versão mais antiga do Java), use

  • UNIX, Linux e Mac OS X: ps-el | grep java
  • Windows: pressione Ctrl+Shift+Esc para abrir o gerenciador de tarefas e localizar o PID do processo Java

Etapa 2: solicitar um despejo de thread da JVM

jstack

Se estiver instalado/disponível, recomendamos usar o jstack ferramenta. Ele imprime despejos de thread no console da linha de comando.

Para obter um despejo de thread usando jstack, execute o seguinte comando:
jstack -l < pid>

Você pode enviar despejos de thread consecutivos para um arquivo usando a diretiva de redirecionamento/acréscimo de saída do console:
jstack -l < pid> > > threaddumps.log

Notas:

  • A ferramenta jstack está disponível desde o JDK 1.5 (para o JVM no Windows, ela está disponível somente em algumas versões do JDK 1.5 e JDK 1.6).

  • jstack funciona mesmo se a variável -Xrs o parâmetro jvm está ativado

  • Não é possível usar a ferramenta jstack do JDK 1.6 para remover threaddumps de um processo em execução no JDK 1.5.

  • No Linux e no UNIX, você precisa executar o comando como o usuário proprietário do processo java:

    sudo - u java-user jstack -l < pid>

    (< java-user> deve ser substituído pela id do usuário com o qual o processo Java está sendo executado)

  • No Windows, se você executar o jstack e receber o erro "Não há armazenamento suficiente disponível para processar este comando", será necessário executar o jstack como o usuário SYSTEM do Windows ou o usuário proprietário do processo java.  Você pode fazer isso usando psexec que você pode baixar aqui. Para executar jstack como usuário SYSTEM, use um comando como este:

    psexec -s jstack < pid>  > > threaddumps.log

    Se você não conseguir instalar o psexec no servidor, crie um arquivo .bat contendo o comando e execute-o usando o agendador de tarefas do Windows (como um usuário diferente).

  • Se o processo java não estiver respondendo, às vezes pode ser útil usar a opção -J-d64 (em sistemas de 64 bits), por exemplo:

    jstack -J-d64 -l <pid> > > threaddumps.log

  • Se o comando jstack (jstack -l < pid> > > threaddumps.log) aciona o erro [ 1] abaixo e, em seguida, execute o comando como o usuário proprietário do processo java.  Por exemplo:

    sudo -u sling jstack -l < pid> > > threaddumps.log

Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 22893: Operation not permitted

sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 22893: Operation not permitted

...

Caused by: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 22893: Operation not permitted

...

sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.run(LinuxDebuggerLocal.java:138)

SCRIPT JSTACK

Aqui está um script (adaptado a partir de eclipse.org) que terá uma série de despejos de thread usando jstack.  Ele também utiliza o uso da cpu em nível de thread usando o comando top.

Basta executá-lo assim:
sudo - u *< usuário>*jstackSeries.sh < pid> < aemserveruser> < count> < atraso>

Por exemplo:
sudo -u aemuser jstackSeries.sh 1234 aemserveruser 10 3

  • 1234 é a pid do processo Java
  • cq5serveruser é o usuário Linux ou UNIX com o qual o processo Java é executado
  • 10 é quantos despejos de thread devem ser executados
  • 3 é o atraso entre cada despejo

Nota: A saída superior tem a id de thread nativa em formato decimal, enquanto a saída jstack tem a nid em hexadecimal.  Você pode fazer a correspondência da thread de alta CPU da saída superior para a saída jstack convertendo a id da thread em hexadecimal.

Além do script acima, também temos um Script do Windows Powershell e um script específico do Adobe AEM no github.

MANEIRAS ALTERNATIVAS DE OBTER UM DESPEJO DE THREAD

Se a variável jstack não estiver disponível para você, você poderá fazer os despejos de thread da seguinte maneira:

Nota: Algumas ferramentas não podem retirar despejos de thread da JVM se o parâmetro de linha de comando -Xrs está ativado. Se você tiver problemas ao fazer despejos de thread, verifique se essa opção está ativada.

UNIX, Mac OS X e Linux (JDK 1.4 ou versão anterior)

No UNIX, Mac OS X e Linux, você pode enviar um sinal QUIT para o processo Java para instruí-lo a produzir um dump de encadeamento para a saída padrão.

  1. Execute este comando para fazer isso:

    kill - QUIT <pid>

    Talvez seja necessário executar esse comando como sudo - u usuário kill - QUIT <pid> onde "user" é o usuário com o qual o processo Java está sendo executado.

  2. Se você estiver iniciando o CQSE usando a variável crx-quickstart/server/start , os despejos de thread serão enviados para crx-quickstart/server/logs/startup.log. Se você estiver usando um servidor de aplicativos de terceiros, como JBoss, WebSphere, Tomcat ou outro, consulte a documentação do servidor para descobrir a qual arquivo a saída padrão é direcionada.

Windows:

JDK 1.X

  1. Baixar javadump.exe (anexado abaixo).

  2. Inicie a JVM com estes três argumentos (eles devem estar na ordem correta):

    -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=C:\temp\jvmoutput.log

  3. Pressione Ctrl+Shift+Esc para abrir o Gerenciador de tarefas.

  4. Localize o PID do processo Java.

  5. Na linha de comando, execute

    javadump.exe <pid>

  6. O despejo de thread aparecerá no jvmoutput.log mencionado na etapa 2.

JDK 1.6

Obter um despejo de thread de jconsole usando um plug-in: [ 0]

Veja como solicitar um despejo de thread:

  1. Adicione o seguinte parâmetro ao comunicado de execução jvm: -Dcom.sun.management.jmxremote

  2. Baixe e instale o JDK 1.6 (se ainda não tiver sido feito).

  3. Baixe e extraia o Utilitário Analisador de despejo de encadeamento. [ 1]

  4. Executar jconsole.exe do JDK 1.6:

    jconsole.exe -pluginpath /path/to/file/tda.jar

  5. Clique em Despejos de encadeamento guia.

  6. Clique em Despejo do encadeamento de solicitação link.

Nota: Se você estiver executando o AEM 6.* e quiser observar as threads em execução, você poderá solicitar http://<host>:<port>/system/console/status-Threads para obter uma lista de threads. No entanto, observe que esses despejos de thread não funcionarão com ferramentas de análise de despejo de thread, como samurai ou tda.

Aplicável a

Todos os produtos Adobe em execução em uma JVM

Ferramentas de análise de despejo de thread:

[ 0]  PsExec v2.42 em Sysinternals na documentação do Microsoft.
[ 1] TDA - Analisador de despejo de thread em irockel/tda em Github.com.
[ 2]  Analisador de despejo de thread Java no FastThread.
[ 3]  Analisador de despejo de thread e monitor do IBM para Java na Documentação do Assistente de suporte da IBM.

Nesta página