Gerando Thread Dumps Programaticamente com a Nova API do Java

Tiago Souza

por Tiago Souza | 2026-06-04

Quando precisamos diagnosticar problemas de performance, deadlocks ou travamentos em aplicações Java, uma das ferramentas mais valiosas disponíveis é o thread dump.

Tradicionalmente, gerar um thread dump exigia o uso de ferramentas externas como jstack, jcmd ou até mesmo acesso direto ao processo da JVM. Com as versões mais recentes do JDK, isso mudou: agora é possível gerar thread dumps programaticamente por meio da interface HotSpotDiagnosticMXBean.

Neste artigo, vamos explorar a nova API dumpThreads(), entender seus casos de uso e aprender como utilizá-la em aplicações reais.

O que é um Thread Dump?

Um thread dump é uma fotografia do estado de todas as threads de uma JVM em um determinado momento.

Ele normalmente contém informações como:

Essa informação é extremamente útil para investigar:

A Nova API dumpThreads()

A interface HotSpotDiagnosticMXBean ganhou um novo método chamado dumpThreads().

Sua assinatura é semelhante a:

public void dumpThreads(
    String outputFile,
    ThreadDumpFormat format
) throws IOException;

O método recebe:

Os formatos disponíveis são:

HotSpotDiagnosticMXBean.ThreadDumpFormat.TEXT_PLAIN
HotSpotDiagnosticMXBean.ThreadDumpFormat.JSON

Isso permite gerar dumps tanto para análise manual quanto para processamento automatizado.

Criando um Utilitário para Gerar Thread Dumps

Vamos criar um método simples para gerar um dump em formato JSON.

import com.sun.management.HotSpotDiagnosticMXBean;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;

public class ThreadDumpUtil {

    public static void takeThreadDump(String outputFile) {

        var hotSpotDiagnosticMXBean =
                ManagementFactory.getPlatformMXBean(
                        HotSpotDiagnosticMXBean.class);

        try {

            if (!new File(outputFile).isAbsolute()) {
                throw new IllegalArgumentException(
                        "O caminho do arquivo deve ser absoluto.");
            }

            hotSpotDiagnosticMXBean.dumpThreads(
                    outputFile,
                    HotSpotDiagnosticMXBean.ThreadDumpFormat.JSON);

        } catch (IOException e) {
            throw new RuntimeException(
                    "Erro ao gerar thread dump",
                    e);
        }
    }
}

A utilização é bastante simples:

ThreadDumpUtil.takeThreadDump(
        "/tmp/thread-dump.json");

Após a execução, o arquivo será criado no caminho informado.

Atenção ao Caminho do Arquivo

Um detalhe importante é que o método exige um caminho absoluto.

Exemplo válido:

"/tmp/thread-dump.json"

Exemplo inválido:

"thread-dump.json"

Caso um caminho relativo seja informado, uma exceção será lançada.

Por isso, é uma boa prática validar o caminho antes de chamar a API.

TEXT_PLAIN vs JSON

Uma das novidades mais interessantes é o suporte nativo ao formato JSON.

Formato Texto

hotSpotDiagnosticMXBean.dumpThreads(
    "/tmp/threads.txt",
    HotSpotDiagnosticMXBean.ThreadDumpFormat.TEXT_PLAIN);

O resultado será semelhante ao que vemos ao executar um jstack:

"main" #1
java.lang.Thread.State: RUNNABLE
...

Esse formato é ideal para análise humana.

Formato JSON

hotSpotDiagnosticMXBean.dumpThreads(
    "/tmp/threads.json",
    HotSpotDiagnosticMXBean.ThreadDumpFormat.JSON);

O resultado passa a ser estruturado:

{
  "threadName": "main",
  "threadId": 1,
  "threadState": "RUNNABLE"
}

Esse formato é excelente para:

Casos de Uso em Produção

Gerar Dumps Quando Houver Muitas Falhas

Imagine uma aplicação começando a apresentar timeouts em massa.

Podemos capturar automaticamente um dump para análise posterior:

if (timeoutCount > 100) {
    ThreadDumpUtil.takeThreadDump(
        "/var/log/dumps/timeouts.json");
}

Isso ajuda a entender exatamente o que estava acontecendo na JVM durante o incidente.

Expor um Endpoint Administrativo

Outra estratégia comum é disponibilizar um endpoint interno para gerar dumps sob demanda.

@PostMapping("/admin/thread-dump")
public void threadDump() {
    ThreadDumpUtil.takeThreadDump(
        "/tmp/admin-dump.json");
}

Essa abordagem é bastante útil em ambientes Kubernetes ou plataformas onde não existe acesso direto ao sistema operacional.

Capturar Informações Antes do Encerramento

Também é possível registrar um shutdown hook para gerar um dump antes da aplicação ser finalizada.

Runtime.getRuntime().addShutdownHook(
    new Thread(() ->
        ThreadDumpUtil.takeThreadDump(
            "/logs/shutdown.json")
    )
);

Isso pode ser útil para investigar encerramentos inesperados.

Diagnóstico Remoto via JMX

Como a funcionalidade é exposta por meio de um MXBean, ferramentas de monitoramento podem acioná-la remotamente utilizando JMX.

Isso elimina a necessidade de acessar diretamente o servidor para coletar informações da JVM.

Em ambientes corporativos, essa capacidade pode simplificar bastante o processo de troubleshooting.

Comparando com jstack

| Recurso | jstack | dumpThreads() | | ---------------------------------- | -------- | ------------- | | Requer acesso ao processo | Sim | Não | | Pode ser automatizado | Limitado | Sim | | Disponível via JMX | Não | Sim | | Suporte a JSON | Não | Sim | | Pode ser usado dentro da aplicação | Não | Sim |

Ferramentas como jstack e jcmd continuam sendo excelentes para análises manuais.

Por outro lado, a nova API é muito mais interessante quando o objetivo é automatizar diagnósticos e integrar informações da JVM a plataformas de observabilidade.

Conclusão

A nova API dumpThreads() representa uma evolução importante para diagnósticos em aplicações Java.

Entre seus principais benefícios estão:

Se você trabalha com observabilidade, monitoramento ou construção de ferramentas operacionais para JVMs, vale a pena explorar essa funcionalidade.

Ela permite transformar uma tarefa tradicionalmente manual em algo totalmente automatizado e integrado ao ciclo de operação da aplicação.