Compartilhar via


Ferramenta de análise de heap (dotnet-gcdump)

Este artigo se aplica a: ✔️ dotnet-gcdump versão 10.0 e versões posteriores

Instalar

Há duas maneiras de baixar e instalar o dotnet-gcdump:

Observação

Para usar dotnet-gcdump em um aplicativo x86, você precisa de uma versão x86 correspondente da ferramenta.

Sinopse

dotnet-gcdump [-h|--help] [--version] <command>

Descrição

A ferramenta global dotnet-gcdump coleta despejos de GC (Coletor de Lixo) de processos .NET ao vivo usando EventPipe. Os despejos de GC são criados disparando um GC no processo de destino, ativando eventos especiais e regenerando o grafo de raízes de objeto do fluxo de eventos. Esse processo permite que despejos de GC sejam coletados enquanto o processo está em execução e com sobrecarga mínima. Esses despejos são úteis para vários cenários:

  • Comparar o número de objetos no heap em vários pontos no tempo.
  • Analisar raízes de objetos (respondendo a perguntas como: "O que ainda tem uma referência a esse tipo?").
  • Coletar estatísticas gerais sobre as contagens de objetos no heap.

Exibir o despejo de GC capturado de dotnet-gcdump

No Windows, arquivos .gcdump podem ser exibidos no PerfView para análise ou no Visual Studio. Atualmente, não há nenhuma maneira de abrir uma .gcdump em plataformas que não sejam Windows.

Você pode coletar vários .gcdumps e abri-los simultaneamente no Visual Studio para obter uma experiência de comparação.

Opções

  • --version

    Exibe a versão do serviço dotnet-gcdump.

  • -h|--help

    Mostra a ajuda da linha de comando.

Comandos

Comando
dotnet-gcdump collect
dotnet-gcdump ps
relatório dotnet-gcdump

dotnet-gcdump collect

Coleta um despejo de GC de um processo em execução no momento.

Aviso

Para percorrer o heap do GC, esse comando dispara uma coleta de lixo de geração 2 (completa), que pode suspender o runtime por um longo tempo, especialmente quando o heap do GC é grande. Não use esse comando em ambientes sensíveis ao desempenho quando o heap do GC for grande.

Sinopse

dotnet-gcdump collect [-h|--help] [-p|--process-id <pid>] [-o|--output <gcdump-file-path>] [-v|--verbose] [-t|--timeout <timeout>] [-n|--name <name>] [--dsrouter <ios|ios-sim|android|android-emu>]

Opções

  • -h|--help

    Mostra a ajuda da linha de comando.

  • -p|--process-id <pid>

    A ID do processo do qual coletar o despejo de GC.

    Observação

    No Linux e no macOS, usar essa opção requer o aplicativo de destino e dotnet-gcdump compartilhar a mesma TMPDIR variável de ambiente. Caso contrário, o comando terá um tempo limite.

  • -o|--output <gcdump-file-path>

    O caminho onde os despejos de GC coletados devem ser gravados. O padrão é .\YYYYMMDD_HHMMSS_<pid.gcdump>.

  • -v|--verbose

    Gere o log durante a coleta do despejo de GC.

  • -t|--timeout <timeout>

    Desista de coletar o despejo de GC se demorar mais do que esses vários segujndos. O valor padrão é 30.

  • -n|--name <name>

    O nome do processo do qual coletar o despejo de GC.

    Observação

    No Linux e no macOS, usar essa opção requer o aplicativo de destino e dotnet-gcdump compartilhar a mesma TMPDIR variável de ambiente. Caso contrário, o comando terá um tempo limite.

  • --diagnostic-port <port-address[,(listen|connect)]>

    Define a porta de diagnóstico usada para se comunicar com o processo a ser despejado. dotnet-gcdump e o runtime do .NET dentro do processo de destino devem concordar com o endereço da porta, com um escutando e o outro se conectando. dotnet-gcdump determina automaticamente a porta correta ao anexar usando as opções ou--process-id.--name Geralmente, só é necessário especificar a porta explicitamente ao se comunicar com um processo em execução dentro de um contêiner que não faz parte do namespace de processo atual.

    As port-address diferenças por sistema operacional:

    • Linux e macOS – um caminho para um soquete de domínio unix, como /foo/tool1.socket.
    • Windows – um caminho para um pipe nomeado, como \\.\pipe\my_diag_port1.
    • Android, iOS e tvOS – um IP:port como 127.0.0.1:9000.

    Por padrão, dotnet-gcdump escuta no endereço especificado. Você pode solicitar dotnet-gcdump para se conectar, acrescentando ,connect após o endereço. Por exemplo, --diagnostic-port /foo/tool1.socket,connect se conectará a um processo de runtime do .NET que está escutando o /foo/tool1.socket soquete de domínio unix.

  • --dsrouter <ios|ios-sim|android|android-emu>

    Inicia o dotnet-dsrouter e conecta-se a ele. Requer que o dotnet-dsrouter seja instalado. Execute dotnet-dsrouter -h para obter mais informações.

Observação

Para coletar um despejo de GC usando dotnet-gcdump, ele precisa ser executado como o mesmo usuário que o usuário que executa o processo de destino ou como raiz. Caso contrário, a ferramenta não estabelecerá uma conexão com o processo de destino.

Exemplos

  • Coletar um despejo de GC de um processo com a ID do processo 1902:

    > dotnet-gcdump collect --process-id 1902
    Writing gcdump to './20250601_121500_1902.gcdump'...
        Finished writing 5763432 bytes.
    
  • Colete um despejo de GC de um processo com a ID do processo 1902 e salve-o em um caminho personalizado:

    > dotnet-gcdump collect --process-id 1902 --output ./myapp-dump.gcdump
    Writing gcdump to './myapp-dump.gcdump'...
        Finished writing 5763432 bytes.
    
  • Colete um despejo de GC de um processo por nome com saída detalhada:

    > dotnet-gcdump collect --name my-aspnet-server --verbose
    [20:54:11] Starting gcdump collection...
    [20:54:11] Triggering GC...
    [20:54:12] Writing gcdump to './20250601_205412_4521.gcdump'...
        Finished writing 5763432 bytes.
    
  • Colete um despejo de GC com um tempo limite personalizado de 60 segundos:

    > dotnet-gcdump collect --process-id 1902 --timeout 60
    Writing gcdump to './20250601_121500_1902.gcdump'...
        Finished writing 5763432 bytes.
    

dotnet-gcdump ps

Lista os processos de dotnet para os quais os despejos de GC podem ser coletados. dotnet-gcdump 6.0.320703 e posteriores também exibem os argumentos de linha de comando com os quais cada processo foi iniciado, se disponível.

Sinopse

dotnet-gcdump ps [-h|--help]

Exemplo

Suponha que você inicie um aplicativo de longa execução usando o comando dotnet run --configuration Release. Em outra janela, execute o aplicativo de longa execução usando o comando dotnet-gcdump ps. A saída que você verá é a seguinte. Os argumentos de linha de comando, se houver, são mostrados usando dotnet-gcdump versão 6.0.320703 e posterior.

> dotnet-gcdump ps
  
  21932 dotnet     C:\Program Files\dotnet\dotnet.exe     run --configuration Release
  36656 dotnet     C:\Program Files\dotnet\dotnet.exe

dotnet-gcdump report <gcdump_filename>

Gerar um relatório de um despejo de GC gerado anteriormente ou de um processo em execução e gravar em stdout.

Sinopse

dotnet-gcdump report [-h|--help] [-p|--process-id <pid>] [-t|--report-type <HeapStat>]

Opções

  • -h|--help

    Mostra a ajuda da linha de comando.

  • -p|--process-id <pid>

    A ID do processo do qual coletar o despejo de GC.

  • -t|--report-type <HeapStat>

    O tipo de relatório a ser gerado. Opções disponíveis: heapstat (padrão).

Exemplos

  • Gere um relatório de estatísticas de heap de um arquivo criado .gcdump anteriormente:

    > dotnet-gcdump report ./20250601_121500_1902.gcdump
    

    A saída exibe estatísticas de tipo:

              Size (Bytes) Count       Type
            ============== =====       ====
            1,603,588,000  22,000,000  System.String
              201,096,000   2,010,000  System.Byte[]
              100,000,000   1,000,000  System.Char[]
               50,000,000     500,000  System.Object[]
               25,000,000     250,000  MyApp.Customer
    
  • Gere um relatório de estatísticas de heap de um processo em execução com a ID do processo 1902:

    > dotnet-gcdump report --process-id 1902
    

Solucionar problemas

  • Não há informações de tipo no gcdump.

    Antes do .NET Core 3.1, havia um problema em que um cache de tipo não era limpo entre gcdumps quando eles eram invocados com EventPipe. Isso resultava nos eventos necessários para determinar que as informações de tipo não eram enviadas para o segundo e posterior gcdumps. Isso foi corrigido no .NET Core 3.1-preview2.

  • COM e tipos estáticos não estão no despejo de GC.

    Antes do .NET Core 3.1, havia um problema em que tipos estáticos e COM não eram enviados quando o despejo de GC era invocado por meio do EventPipe. Isso foi corrigido no .NET Core 3.1.

  • dotnet-gcdump não consegue gerar um arquivo .gcdump devido a informações ausentes, por exemplo, [Error] Exception during gcdump: System.ApplicationException: o arquivo ETL mostra o início de um despejo de heap, mas não sua conclusão. Ou o arquivo .gcdump não inclui o heap inteiro.

    dotnet-gcdump funciona coletando um rastreamento de eventos emitidos pelo coletor de lixo durante uma coleta de geração 2 induzido. Se o heap for suficientemente grande ou não houver memória suficiente para dimensionar os buffers de evento, os eventos necessários para reconstruir o gráfico de heap do rastreamento poderão ser descartados. Nesse caso, para diagnosticar problemas com o heap, é recomendável coletar um despejo do processo.

  • dotnet-gcdump parece causar um problema de memória insuficiente em um ambiente com restrição de memória.

    dotnet-gcdump funciona coletando um rastreamento de eventos emitidos pelo coletor de lixo durante uma coleta de geração 2 induzido. O buffer da coleção de eventos pertence ao aplicativo de destino e pode crescer até 256 MB. o próprio dotnet-gcdump também usa memória. Se o ambiente for restrito à memória, certifique-se de considerar esses fatores ao coletar um gcdump para evitar erros.