Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este estudo de caso demonstra como usar ferramentas de criação de perfil do Visual Studio para identificar e resolver problemas de desempenho em uma amostra ASP.NET aplicativo. Para obter uma comparação das ferramentas de criação de perfil, consulte Qual ferramenta devo escolher?
O que você aprenderá:
- Como usar as ferramentas de criação de perfil do Visual Studio para analisar o desempenho do aplicativo.
- Como interpretar dados de perfilamento para encontrar gargalos.
- Estratégias práticas para otimizar o código usando contadores .NET, contagens de chamadas e dados de tempo.
Aplique essas técnicas para melhorar seus próprios aplicativos.
Isolar um estudo de caso sobre um problema de desempenho
O aplicativo ASP.NET de exemplo executa consultas em um banco de dados simulado e se baseia no Exemplo de Diagnóstico.
Principais sintomas de desempenho:
- Baixo uso da CPU: a CPU não é o gargalo.
- Alta contagem de threads do ThreadPool: a contagem de threads aumenta constantemente, indicando o esgotamento do pool de threads.
- Resposta lenta do aplicativo: o aplicativo responde lentamente devido à falta de threads disponíveis.
Este estudo de caso usa ferramentas de criação de perfil do Visual Studio para identificar e resolver esses problemas, ajudando você a tornar seu código mais rápido e eficiente.
Desafio
Corrigir esses problemas envolve vários desafios:
- Diagnosticar gargalos: o baixo uso da CPU com desempenho lento pode ter várias causas. O uso efetivo de ferramentas de análise de desempenho e a interpretação dos seus resultados são essenciais.
- Restrições de conhecimento e recursos: a criação de perfil e a otimização exigem habilidades e experiência específicas, que podem nem sempre estar disponíveis.
Uma abordagem estratégica que combina ferramentas de criação de perfil, conhecimento técnico e testes cuidadosos é fundamental para superar esses desafios.
Estratégia
Aqui está uma visão de alto nível da abordagem neste estudo de caso:
- Comece monitorando as métricas do contador do .NET durante a coleta de dados de desempenho. A ferramenta .NET Counters do Visual Studio é um bom ponto de partida.
- Para obter insights mais profundos, colete traços com ferramentas adicionais de criação de perfil, como a ferramenta de instrumentação para contagens de chamadas e dados de tempo.
A coleta de dados requer as seguintes tarefas:
- Defina o aplicativo como versão de compilação.
- Selecione a ferramenta Contadores do .NET no Perfil de Performance (Alt+F2).
- Inicie o aplicativo e colete um traço.
Verificar contadores de desempenho
Durante a execução do aplicativo, observamos os contadores na ferramenta .NET Counters. Para investigações iniciais, algumas métricas importantes para ficar de olho incluem:
-
CPU Usage. Assista a este contador para ver se ocorre um problema de desempenho com uso alto ou baixo da CPU. Isso pode ser uma pista para tipos específicos de problemas de desempenho. Por exemplo:- Quando houver alto uso da CPU, use a Ferramenta Uso da CPU para identificar áreas onde possamos otimizar o código. Para obter um tutorial sobre isso, consulte Estudo de caso: guia do iniciante para otimizar o código.
- Se houver uso baixo da CPU, use a ferramenta Instrumentação para identificar contagens de chamadas e tempo médio de função com base no tempo do relógio de parede. Isso pode ajudar a identificar problemas como contenção ou privação do pool de threads.
-
Allocation Rate. Para um aplicativo Web que atende solicitações, a taxa deve ser bastante estável. -
GC Heap Size. Observe este contador para ver se o uso de memória está crescendo continuamente e se há um potencial vazamento de memória. Se parecer alto, use uma das ferramentas de uso de memória. -
Threadpool Thread Count. Para um aplicativo Web que atende solicitações, monitore esse contador para ver se a contagem de threads está mantendo-se estável ou subindo a uma taxa estável.
Aqui está um exemplo mostrando como a CPU Usage é baixa, enquanto a ThreadPool Thread Count é relativamente alta.
Uma contagem de threads cada vez maior com um baixo uso da CPU pode ser um indicador de insuficiência do pool de threads. O pool de threads é forçado a continuar iniciando novos threads. A insuficiência do pool de threads ocorre quando o pool não tem threads disponíveis para processar novos itens de trabalho e costuma causar lentidão na resposta dos aplicativos.
Com base no baixo uso da CPU e na contagem relativamente alta de threads, e trabalhando com a hipótese de um possível caso de insuficiência do pool de threads, mude para a ferramenta Instrumentação.
Investigar contagens de chamadas e dados de temporização
Vamos dar uma olhada em um rastreamento da ferramenta Instrumentação para ver se conseguimos descobrir mais sobre o que está acontecendo com os threads.
Depois de coletar um rastreamento com a ferramenta Instrumentação e carregá-lo no Visual Studio, primeiro verificamos a página de relatório inicial .diagsession que mostra os dados resumidos. No rastreamento coletado, usamos o link Abrir detalhes no relatório e selecionamos Flame Graph.
A visualização do Gráfico de Chamas nos mostra que a função QueryCustomerDB (mostrada em amarelo) é responsável por uma parte significativa do tempo de execução do aplicativo.
Clique com o botão direito do mouse na função QueryCustomerDB e escolha Exibir na árvore de chamadas.
O caminho do código com maior uso de CPU no aplicativo é chamado de caminho frequente. O ícone de chama de caminho frequente (
) pode ajudar a identificar rapidamente problemas de desempenho que podem ser melhorados.
Na exibição Árvore de Chamadas, você pode ver que o caminho frequente inclui a função QueryCustomerDB, o que aponta para um possível problema de desempenho.
Em relação ao tempo gasto em outras funções, os valores Self e Avg Self para a função QueryCustomerDB são muito altos. Ao contrário de Total e Média total, os valores de Próprio excluem o tempo gasto em outras funções, portanto, esse é um bom lugar para procurar o gargalo de desempenho.
Dica
Se os valores Self fossem relativamente baixos em vez de altos, você provavelmente gostaria de examinar as consultas reais chamadas pela função QueryCustomerDB.
Clique duas vezes na função QueryCustomerDB para mostrar o código-fonte da função.
public ActionResult<string> QueryCustomerDB()
{
Customer c = QueryCustomerFromDbAsync("Dana").Result;
return "success:taskwait";
}
Nós fazemos uma pequena pesquisa. Como alternativa, podemos economizar tempo e deixar Copilot fazer a pesquisa por nós.
Se estivermos usando o Copilot, selecionamos Perguntar ao Copilot no menu de contexto e digitamos a seguinte pergunta:
Can you identify a performance issue in the QueryCustomerDB method?
Dica
Você pode usar comandos com barra, como /otimizar para ajudar a formar boas perguntas para o Copilot.
Copilot nos diz que esse código está chamando uma API assíncrona sem usar await. Esse é o padrão de código síncrono sobre assíncrono, que é uma causa comum de insuficiência do pool de threads e pode bloquear threads.
Para solucionar, use await. Neste exemplo, Copilot fornece a seguinte sugestão de código junto com a explicação.
public async Task<ActionResult<string>> QueryCustomerDB()
{
Customer c = await QueryCustomerFromDbAsync("Dana");
return "success:taskwait";
}
Se você vir problemas de desempenho relacionados a consultas de banco de dados, poderá usar a ferramenta banco de dados para investigar se determinadas chamadas são mais lentas. Esses dados podem indicar uma oportunidade de otimizar consultas. Para obter um tutorial que mostra como usar a ferramenta Banco de Dados para investigar um problema de desempenho, consulte Estudo de caso: guia do iniciante para otimizar o código. A ferramenta Banco de Dados dá suporte ao .NET Core com ADO.NET ou Entity Framework Core.
Para obter visualizações no Visual Studio para comportamento individual de thread, você pode usar a janela Pilhas paralelas durante a depuração. Essa janela mostra threads individuais juntamente com informações sobre threads que estão aguardando, as threads que elas estão aguardando e deadlocks.
Para obter mais informações sobre a insuficiência do pool de threads, consulte Detectando a insuficiência do pool de threads.
Próximas etapas
Os artigos e postagens de blog a seguir fornecem mais informações para ajudá-lo a aprender a usar as ferramentas de desempenho do Visual Studio com eficiência.
- Estudo de caso: guia do iniciante para otimizar o código
- estudo de caso : desempenho duplo em menos de 30 minutos
- melhorando o desempenho do Visual Studio com a nova ferramenta de instrumentação