Compartilhar via


Medir o uso de memória em Visual Studio (C#, Visual Basic, C++, F#)

Encontre vazamentos de memória e memória ineficiente enquanto estiver depurando com a ferramenta de diagnóstico Uso de Memória integrada ao depurador. A ferramenta Uso de Memória permite que você obtenha um ou mais instantâneos do heap de memória gerenciada e do heap de memória nativa para entender o impacto do uso de memória dos tipos de objeto. Você também pode analisar o uso de memória sem um depurador anexado ou direcionando um aplicativo em execução. Para obter mais informações, confira Executar ferramentas de criação de perfil em builds de versão ou de depuração. Para obter informações sobre como escolher a melhor ferramenta de análise de memória para suas necessidades, consulte Escolha uma ferramenta de análise de memória.

Embora você possa coletar instantâneos de memória a qualquer momento na ferramenta Memory Usage, você pode usar o depurador Visual Studio para controlar como seu aplicativo é executado durante a investigação de problemas de desempenho. A definição de pontos de interrupção, passo a passo, Interromper Tudo e outras ações de depurador podem ajudar você a concentrar as investigações de desempenho nos caminhos de código mais relevantes. Executar essas ações enquanto seu aplicativo está em execução pode eliminar o ruído do código que não interessa a você e pode reduzir significativamente o tempo necessário para diagnosticar um problema.

Dica

Você também pode usar o GitHub Copilot Profiler Agent para obter diretrizes orientadas por IA para coletar e analisar rastreamentos de memória.

Importante

As Ferramentas de Diagnóstico integradas ao depurador são suportadas para o desenvolvimento em .NET no Visual Studio, incluindo aplicativos ASP.NET, ASP.NET Core, desenvolvimento nativo/C++ e em modo misto (.NET e nativo).

Neste tutorial, você irá:

  • Tirar instantâneos da memória
  • Analisar dados de uso de memória

Se Uso de Memória não fornece os dados necessários, outras ferramentas de criação de perfil no Criador de Perfil de Desempenho fornecem diferentes tipos de informações que poderão ser úteis. Em muitos casos, o gargalo de desempenho do seu aplicativo pode ser causado por algo diferente da memória, como o uso da CPU, a renderização da interface do usuário ou o tempo de requisição de rede.

Nota

Suporte para alocador personalizado O profilador de memória nativa funciona coletando dados de evento ETW de alocação emitidos em tempo de execução. Os alocadores no CRT e no SDK do Windows foram anotados no nível de origem para que seus dados de alocação possam ser capturados. Se você estiver escrevendo seus próprios alocadores, todas as funções que retornarem um ponteiro para uma memória heap recém-alocada poderão ser decoradas com __declspec(allocator), como visto neste exemplo de myMalloc:

__declspec(allocator) void* myMalloc(size_t size)

Coletar dados de uso de memória

  1. Abra o project que você deseja depurar no Visual Studio e defina um ponto de interrupção em seu aplicativo no ponto em que você deseja começar a examinar o uso da memória.

    Se você tiver uma área em que suspeitar de um problema de memória, defina o primeiro ponto de interrupção antes que o problema de memória ocorra.

    Dica

    Como pode ser desafiador capturar o perfil de memória de uma operação que lhe interessa quando seu aplicativo aloca e desaloque memória com frequência, defina pontos de interrupção no início e no final da operação (ou percorra a operação) para encontrar o ponto exato em que a memória foi alterada.

  2. Defina um segundo ponto de interrupção no final da função ou região do código que você deseja analisar (ou após ocorrer um problema de memória suspeito).

  3. A janela das Ferramentas de Diagnóstico é exibida automaticamente, a menos que você a tenha desativado. Para abrir a janela novamente, clique em DepurarWindowsMostrar Ferramentas de Diagnóstico.

  4. Escolha Uso de Memória com a configuração Selecionar Ferramentas na barra de ferramentas.

    Captura de tela da janela Ferramentas de Diagnósticos com a ferramenta Uso da Memória selecionada no menu suspenso Selecionar Ferramentas.

    Captura de tela da janela Ferramentas de Diagnósticos com a ferramenta Uso da Memória selecionada no menu suspenso Selecionar Ferramentas.

  5. Clique em Depurar/Iniciar Depuração (ou Iniciar na barra de ferramentas ou F5).

    Quando o aplicativo terminar de ser carregado, a exibição Resumo das Ferramentas de Diagnóstico será exibida.

    Captura de tela da guia Resumo das Ferramentas de Diagnóstico mostrando o grafo da linha do tempo de Uso da Memória e o gráfico de memória do processo.

    Nota

    Como a coleta de dados de memória pode afetar o desempenho de depuração de seus aplicativos nativos ou de modo misto, os instantâneos de memória são desabilitados por padrão. Para habilitar instantâneos de aplicativos mistos ou nativos, inicie uma sessão de depuração (Tecla de atalho: F5). Quando a janela Ferramentas de Diagnóstico for exibida, escolha a guia Uso de Memória e, em seguida, Criação de Perfil de Heap.

    Captura de tela da barra de ferramentas Uso de Memória com o botão de Perfilamento de Heap destacado para ativar snapshots para aplicativos nativos ou de modo misto.

    Parar (tecla de atalho: ShiftF5) e reiniciar a depuração.

    Captura de tela da guia Resumo das Ferramentas de Diagnóstico mostrando o grafo da linha do tempo de Uso da Memória e o gráfico de memória do processo.

    Nota

    Como a coleta de dados de memória pode afetar o desempenho de depuração de seus aplicativos nativos ou de modo misto, os instantâneos de memória são desabilitados por padrão. Para habilitar instantâneos de aplicativos mistos ou nativos, inicie uma sessão de depuração (Tecla de atalho: F5). Quando a janela Ferramentas de Diagnóstico for exibida, escolha a guia Uso de Memória e, em seguida, Criação de Perfil de Heap.

    Captura de tela da barra de ferramentas Uso de Memória com o botão de Perfilamento de Heap destacado para ativar snapshots para aplicativos nativos ou de modo misto.

    Parar (tecla de atalho: ShiftF5) e reiniciar a depuração.

  6. Para obter um instantâneo no início da sessão de depuração, escolha Tirar instantâneo na barra de ferramentas de resumo Uso de Memória. (Pode ajudar a definir um ponto de interrupção aqui também.)

    Captura de tela da barra de ferramentas de resumo do Uso de Memória com o botão Tirar Captura.

    Dica

    Para criar uma linha de base para comparações de memória, considere tirar um instantâneo no início da sessão de depuração.

  7. Execute o cenário que fará com que o primeiro ponto de interrupção seja atingido.

  8. Enquanto o depurador estiver pausado no primeiro ponto de interrupção, escolha Tirar instantâneo na barra de ferramentas de resumo Uso de Memória.

  9. Pressione F5 para executar o aplicativo até o seu segundo ponto de interrupção.

  10. Agora, crie outro instantâneo.

Neste ponto, você pode começar a analisar os dados.

Se você tiver problemas para coletar ou exibir dados, veja Solucionar erros de perfilamento e corrigir problemas.

Analisar dados de uso de memória

As linhas da tabela de resumo de Uso de Memória listam os instantâneos obtidos durante a sessão de depuração e fornecem links para exibições mais detalhadas.

Captura de tela da tabela de resumo do uso de memória exibindo dois instantâneos com colunas para Objetos, Tamanho do Heap e suas diferenças.

O nome da coluna depende do modo de depuração escolhido nas propriedades do projeto: .NET, nativo ou misto (.NET e nativo).

  • A coluna Objects (Diff) (.NET) ou Allocations (Diff) (C++) exibe o número de objetos na memória .NET ou nativa quando o instantâneo foi tirado.

  • A coluna Heap Size (Diff) exibe o número de bytes nos heaps do .NET e nativos

Quando você tira vários instantâneos, as células da tabela de resumo incluem a alteração no valor entre o instantâneo de linha e o instantâneo anterior.

Para analisar o uso da memória, clique em um dos links que abre um relatório detalhado do uso de memória:

  • Para exibir detalhes da diferença entre o instantâneo atual e o instantâneo anterior, escolha o link de alteração à esquerda da seta (Aumento do Uso de MemóriaAumento de Uso de Memória). Uma seta vermelha indica um aumento no uso de memória e uma seta verde indica uma diminuição.

Dica

Para ajudar a identificar problemas de memória mais rapidamente, os relatórios de comparação são classificados pelos tipos de objeto que mais aumentaram no número geral (clique no link de alteração na coluna Objetos (Comparação)) ou que mais aumentaram quanto ao tamanho geral do heap (clique no link de alteração na coluna Tamanho do Heap (Comparação)).

  • Para exibir detalhes apenas do instantâneo selecionado, clique no link que não permite alterações.

    O relatório é exibido em uma janela separada.

Relatórios de tipos gerenciados

Escolha o link atual de uma célula Objects (Diff) na tabela resumo de Uso de Memória.

Captura de tela do relatório de tipo gerenciado.relatório de tipo gerenciado

Nota

Para código .NET, o ícone Exibir Detalhes (o ícone da instância na coluna Tipo de Objeto) está disponível apenas ao usar a ferramenta de uso de memória integrada ao debugger ou quando você abre um instantâneo de heap e escolhe Depurar Memória Gerenciada.

O painel superior mostra a contagem e o tamanho dos tipos no instantâneo, incluindo o tamanho de todos os objetos referenciados pelo tipo (inclusive tamanho).

A árvore Caminhos para Raiz no painel inferior exibe os objetos que fazem referência ao tipo selecionado no painel superior. O coletor de lixo .NET limpa a memória de um objeto somente quando o último tipo que faz referência a ele foi liberado. Para obter mais informações sobre como usar a árvore Caminhos para Raiz, confira Analisar o caminho crítico para raiz.

Captura de tela do relatório de tipo gerenciado.relatório de tipo gerenciado

Nota

Para código .NET, o ícone Visualizar Instâncias (O ícone de instância na coluna Tipo de Objeto) só está disponível ao usar a ferramenta de Uso de Memória integrada ao debugger ou ao abrir o instantâneo heap e escolher Depurar Memória Gerenciada.

O painel superior mostra a contagem e o tamanho dos tipos no instantâneo, incluindo o tamanho de todos os objetos referenciados pelo tipo (inclusive tamanho).

A árvore Caminhos para Raiz no painel inferior exibe os objetos que fazem referência ao tipo selecionado no painel superior. O coletor de lixo .NET limpa a memória de um objeto somente quando o último tipo que faz referência a ele foi liberado. Para obter mais informações sobre como usar a árvore Caminhos para Raiz, confira Analisar o caminho crítico para raiz.

A árvore Tipos Referenciados exibe as referências mantidas pelo tipo selecionado no painel superior.

captura de tela do relatório Objetos Referenciados.

A árvore Tipos Referenciados exibe as referências mantidas pelo tipo selecionado no painel superior.

captura de tela do relatório Objetos Referenciados.

Para exibir as instâncias de um tipo selecionado no painel superior, clique no ícone Exibir Detalhes ao lado do tipo de objeto.

Captura de tela da exibição Instâncias na ferramenta Uso de Memória.Exibição Instâncias na ferramenta de Uso de Memória

O modo de exibição Instâncias exibe as instâncias do objeto selecionado no instantâneo no painel superior. O painel Caminhos para Raiz e Objetos Referenciados exibe os objetos que referenciam a instância selecionada e os tipos de que a instância selecionada referencia. Quando o depurador é interrompido no ponto em que o instantâneo foi tirado, você pode passar o mouse sobre a célula Valor para exibir os valores do objeto em uma dica de ferramenta.

Para exibir as instâncias de um tipo selecionado no painel superior, clique no ícone Exibir Instâncias ao lado do tipo de objeto.

Captura de tela da exibição Instâncias na ferramenta Uso de Memória.Exibição Instâncias na ferramenta de Uso de Memória

O modo de exibição Instâncias exibe as instâncias do objeto selecionado no instantâneo no painel superior. O painel Caminhos para Raiz e Objetos Referenciados exibe os objetos que referenciam a instância selecionada e os tipos de que a instância selecionada referencia. Quando o depurador é interrompido no ponto em que o instantâneo foi tirado, você pode passar o mouse sobre a célula Valor para exibir os valores do objeto em uma dica de ferramenta.

Relatórios de tipos nativos

Escolha o link atual de uma célula Alocações (Comparação) ou Tamanho do Heap (Comparação) na tabela de resumo de Uso de Memória da janela Ferramentas de Diagnóstico.

Captura de tela do modo de exibição de Tipo Nativo.

Captura de tela do modo de exibição de Tipo Nativo.

O Modo de exibição de tipos exibe o número e tamanho dos tipos no instantâneo.

  • Escolha o ícone Exibir Detalhes ao lado de um tipo selecionado para exibir informações sobre os objetos do tipo selecionado no instantâneo.

    O modo de exibição Instâncias mostra cada instância do tipo selecionado. A seleção de uma instância exibe a pilha de chamadas resultou na criação da instância no painel Pilha de Chamadas de Alocação. (Essas informações só estão disponíveis durante a depuração.)

    Captura de tela do modo de exibição Instâncias e do painel Pilha de Chamadas de Alocação.

  • Escolha o ícone Exibir Instâncias ao lado de um tipo selecionado para exibir informações sobre os objetos selecionados no instantâneo.

    O modo de exibição Instâncias mostra cada instância do tipo selecionado. A seleção de uma instância exibe a pilha de chamadas resultou na criação da instância no painel Pilha de Chamadas de Alocação. (Essas informações só estão disponíveis durante a depuração.)

    Captura de tela do modo de exibição Instâncias e do painel Pilha de Chamadas de Alocação.

  • Escolha Pilhas para ver a pilha de alocação do tipo selecionado.

    Captura de tela da exibição de Pilhas.

  • Escolha Pilhas para ver a pilha de alocação do tipo selecionado.

    Captura de tela da exibição de Pilhas.

Análises sobre o uso de memória

Para memória gerenciada, a ferramenta Análise de Memória também fornece várias informações automáticas internas avançadas. Selecione a guia Insights nos relatórios de tipos gerenciados e ela mostrará os insights automáticos aplicáveis, como Strings duplicadas e Matrizes esparsas e Perdas do manipulador de eventos.

Captura de tela da exibição de insights na ferramenta Uso de Memória.Aproveitamento de insights de Uso de Memória

Captura de tela da exibição de insights na ferramenta Uso de Memória.Aproveitamento de insights de Uso de Memória

A seção Cadeias de caracteres duplicadas mostra a lista de cadeias de caracteres alocadas várias vezes no heap. Além disso, esta seção mostra o total de memória desperdiçada, ou seja, o (número de instâncias – 1) vezes o tamanho da cadeia de caracteres.

A seção Matrizes Esparsas mostra matrizes preenchidas principalmente com zero elementos, que podem ser ineficientes em termos de desempenho e uso de memória. A ferramenta de análise de memória detectará automaticamente essas matrizes e mostrará a quantidade de memória que está sendo desperdiçada devido a esses valores zero.

A seção Event Handler Leaks, disponível no Visual Studio versão 17.9 preview 1 de 2022, mostra possíveis vazamentos de memória que podem ocorrer quando um objeto assina o evento de outro objeto. Se o publicador do evento sobreviver ao assinante, o assinante continuará existindo, mesmo que não haja outras referências a ele. Isso pode levar a vazamentos de memória, em que a memória não utilizada não é liberada corretamente, fazendo com que o aplicativo use cada vez mais memória ao longo do tempo.

Sabe-se que determinados tipos têm campos que podem ser lidos para determinar o tamanho da memória nativa que possuem. A guia Insights mostra os nós de memória nativos falsos no gráfico de objetos, que foram retidos por seus objetos pai, de modo que a interface do usuário os reconheça e exiba seu tamanho e gráfico de referência.

Captura de tela da exibição de insight nativo na ferramenta de Uso de Memória.exibição de insight nativo na ferramenta de Uso de Memória

Relatórios de comparação (Diff)

  • Escolha o link de alteração em uma célula da tabela de resumo da guia Uso de Memória na janela Ferramentas de Diagnóstico.

    Captura de tela da tabela de resumo de uso de memória com o link para alteração destacado em uma célula da captura.

  • Escolha um instantâneo na lista Comparar com de um relatório gerenciado ou nativo.

    Captura de tela da lista suspensa Comparar em um relatório de Uso de Memória, mostrando os instantâneos disponíveis para comparação.

    Captura de tela da lista suspensa Comparar em um relatório de Uso de Memória, mostrando os instantâneos disponíveis para comparação.

O relatório de alteração adiciona colunas (marcadas com (Diff)) ao relatório base que mostram a diferença entre o valor do instantâneo base e o instantâneo de comparação. Veja como pode ser a aparência de um relatório de comparação Exibição de Tipo Nativo:

Captura de tela da visualização de diferença de tipos nativos.Visualização de diferença de tipos nativos

Captura de tela da visualização de diferença de tipos nativos.Visualização de diferença de tipos nativos

O painel superior mostra a contagem e o tamanho dos tipos no instantâneo, incluindo o tamanho de todos os objetos referenciados pelo tipo (inclusive tamanho).

Blogs e vídeos

Analisar a CPU e a memória durante a depuração

Blog Visual C++: Perfilamento de memória no Visual C++ 2015

Próximas etapas

Neste tutorial, você aprendeu a coletar e analisar dados de uso de memória durante o processo de depuração. Estas são algumas das próximas etapas sugeridas:

  • Para analisar o uso de memória em builds de release, consulte Analisar o uso de memória no Profiler de Desempenho.
  • Para saber uma abordagem geral para otimizar o código usando as ferramentas de criação de perfil, consulte Estudo de caso: guia do iniciante para otimizar o código.
  • Para obter diretrizes de criação de perfil orientadas por IA, consulte Profile seu aplicativo com GitHub Copilot Profiler Agent.
  • Para obter uma visão geral de todas as ferramentas de criação de perfil, consulte Primeiro examinar as ferramentas de criação de perfil.