Como utilizar o Visual Studio para análise de performance — Gerenciamento de Memória

Tiago Tartari
4 min readJun 5, 2020

--

O Visual Studio é uma excelente ferramenta para desenvolvimento de aplicações, em muitos casos pode ser substituído pelo VS Code, mas para cenários de análise de performance não encontro outra alternativa, dentro do âmbito Microsoft, que me forneça um tool set tão rico.

Neste artigo vamos falar como fazer o gerenciamento de memória utilizando o Visual Studio.

Geralmente os desenvolvedores ignoram esse tool set fechando a janela diagnostic tools. Então se você fez isso, para habilitar é bem simples, vá em Debug \ Windows \ Show Diagnostics Tools.

São dois momentos que podemos analisar a performance das nossas aplicações, o primeiro momento é em debug e o outro em release na qual utilizamos o profiler. Nesse post vou tratar em debug.

Analisando a pressão do GC

Pressão no garbage collector é um dos vilões de performance em aplicações .NET, o post Pequenas mudanças no código, impacto gigantesco em produção, trás um pouco mais de detalhes na resolução de problemas de performance.

Em tempo de desenvolvimento, debug, nós conseguimos utilizar as ferramentas disponibilizadas pelo Visual Studio pra essa análise.

Abaixo, mostro a pressão do garbage collector representada pelos pontos em amarelo. Não há uma diferença de cores por gerações, mas ao passar o mouse em cima conseguimos saber qual é a geração que está sendo coletada.

Tirando snapshots da memória.

Precisamos entender o que estamos alocando na memória, neste momento o uso da opção Take Snapshot entra em ação.

O programa para deixar esse comportamento na memória é simples, mas com uma pressão muito alta. Declarei um objeto HasSet<string> e em um for de 0 a 20.000 acumulei o valor em uma string e adicionei ao HashSet<string>, o comportamento é: A memória só vai crescer caracterizando o comportamento de memory leak.

public static void Main(string[] args)
{
var valores = new HashSet<string>();
string valor = "";

for (int i = 0; i < 20000; i++)
{
valor += i.ToString();
valores.Add(valor);
}
Console.ReadLine();
}

Na imagem os pontos em azul são as capturas dos Snapshots, também quero destacar as colunas de Time, Objects e Heap Size.

O primeiro Snapshot ocorreu com 1,9s de execução, no momento tínhamos 1.455 objetos alocados em memória consumindo um pouco mais que 2Mb.

O terceiro Snapshot ocorreu com 4.2s de execução, no momento tínhamos 4.226 objetos alocados em memória, um crescimento de 1.771, saímos de 2Mb para mais de 48Mb de consumo de memória.

Por final, o quarto Snapshot ocorreu com 13.7s de execução resultou em 13.733 objetos alocados em memória, saímos de mais de 48mb para mais de 672Mb de memória.

Analisando os objetos alocados em memória

Para analisar os objetos em memória, pegando o segundo Snapshot, nós temos. O objeto que mais custa para memória é o HashSet<string> com uso de mais de 12Mb alocados.

Ao entrar no principal ofensor, HashSet<string>, nós encontraremos todas as instâncias desse objeto na memória.

Outra visualização, muito utilizada é a comparação entre os Snapshots que nos dá uma visão do crescimento ou diminuição das alocações em memória.

Não há dúvidas que o Visual Studio é uma excelente ferramenta para cenários em que análise de performance é fundamental.

No Visual Studio Summit 2019, abordei sobre este assunto, veja as fotos do evento aqui.

--

--

Tiago Tartari

Microsoft MVP, programador por mais de 18 anos onde 10 deles atuando como arquiteto de soluções para e-commerce, palestrante técnico, apaixonado por performance