Esse artigo faz parte da revista .NET Magazine edição 38. Clique aqui para ler todos os artigos desta edição

 

 

“Se você tiver muita sorte, os seus problemas de performance poderão ser facilmente resolvidos assim que ocorrerem. Mas como na maioria das vezes não é assim que ocorre, você vai ter um enorme esforço para conseguir modificar o seu código, para que alcance um nível de performance aceitável. Esta é uma péssima armadilha para se cair. E na pior das hipóteses, você irá se deparar com uma memorável frase, que às vezes finalizam um projeto: ‘Isto nunca vai funcionar, vamos ter que refazer do zero!’”.

Rico Mariani, Arquiteto, Microsoft.

 

Como você pôde notar, desempenho é uma questão a se preocupar durante o desenvolvimento de um projeto, e nunca após ele estar em produção. Desempenho é um problema de Engenharia de software, e não é responsabilidade apenas do desenvolvedor.

Em geral, todos os integrantes da equipe devem estar envolvidos e comprometidos com o desempenho da aplicação: Arquitetos, Líderes dos Desenvolvedores, Desenvolvedores, Testers, Administradores ou Gerentes de Projeto e em alguns casos, a equipe deve ter um Analista de Desempenho, que será o guia principal da equipe nestas questões.

Este é um assunto muito extenso e veremos aqui apenas alguns pontos sobre esta questão que tira o sono de tanta gente.

 

Por onde começar?

A minha primeira sugestão é que você leia o Guia Improving .NET Application Performance and Scalability (Melhorando a Performance e a Escalabilidade de aplicações .NET). Este é um Guia de arquitetura da Microsoft que você encontra neste link: http://msdn2.microsoft.com/en-us/library/ms998534.aspx

Mesmo que você nunca tenha se preocupado com o desempenho de suas aplicações, sugiro que leia este Guia. Esta é uma literatura obrigatória para Arquitetos e Desenvolvedores .NET.  A maioria das questões abordadas neste artigo foi baseada neste guia.

A quantidade de tópicos que temos sobre desempenho é enorme. E estamos falando apenas de uma fonte. Portanto, não espere achar a solução de todos os seus problemas aqui neste artigo. Repito que este é um problema sério e deve ser tratado com cuidado, e de preferência do início ao fim do projeto.

Os quatro primeiros capítulos do material citado anteriormente falam apenas das questões de Engenharia e Arquitetura que envolvem a Performance da sua aplicação. Mas nós não vamos focar nestes pontos, vamos dar uma olhada em algumas questões de desempenho que podemos usar em projetos ASP.NET.

 

Garbage Collector

Quando falamos de desempenho a primeira coisa que nos vem à mente é Memória. E em .NET sabemos que memória é um assunto relacionado ao Garbage Collector. Mas você sabe o que faz o Garbage Collector?

De forma muito simplista podemos dizer que o Garbage Collector é responsável por liberar espaço de memória que não está sendo mais utilizado. Mas há muito mais sobre o Garbage Collector que você precisa saber.

  O .NET Framework faz a “coleta automática do lixo” para gerenciar a memória das aplicações. Quando você usa o operador new para a criação de um objeto, um determinado espaço de memória é alocado para este objeto. Quando o Garbage Collector decide que uma quantidade suficiente de “lixo” está acumulada na memória, ele realiza uma “coleta”, para liberar um pouco deste espaço.

  Este processo é inteiramente automático, mas há um número de fatores que precisamos tomar cuidado, e que podem tornar este processo mais ou menos eficiente. Para entender os princípios do Garbage Collector, você precisa entender o ciclo de vida de um objeto gerenciado.

A memória é alocada para o objeto, quando você usa o operador new. O construtor do objeto é chamado logo após a alocação da memória. O objeto é utilizado por um período de tempo. O objeto “morre” quando todas as suas referências são explicitamente setadas para null, ou quando o objeto saiu do escopo em que foi criado. A memória utilizada pelo objeto é liberada (coletada) um tempo depois. Depois que a memória é liberada, ela poderá ser utilizada por outros objetos.

Um ponto importante a considerar a respeito de desempenho do processo é o seguinte: Se há memória disponível quando você cria um novo objeto, ela é automaticamente alocada. Agora, se não há memória suficiente disponível, o Garbage Collector irá “reclamar” por memória que esteja ociosa, devido a objetos que não são mais utilizados.

Um erro muito comum é utilizar o método Collect da classe System.GC. Este método força o Garbage Collector a coletar memória. Mas, via de regra, você deve sempre evitar o uso deste método, e deixar que o próprio runtime determine qual é o momento mais apropriado para realizar a coleta.

É comum usarmos método Collect quando notamos que a memória não está sendo liberada. Porém o motivo da memória não estar sendo liberada é que estamos, inadvertidamente, “segurando” estes objetos na memória. E neste caso, o uso do método Collect não vai resolver o problema.

 

Gerenciamento de recursos eficiente

Como acabamos de ver, o Garbage Collector é um excelente recurso do .NET Framework. Porém é preciso cooperar com o GC, no sentido de sempre liberar os objetos que não serão mais utilizados, para que a memória que ocupam seja liberada. O acúmulo de objetos na memória, inevitavelmente irá lhe causar problemas de performance.

Entretanto, há alguns cuidados que precisam ser tomados, principalmente quando estamos falando de acesso a banco de dados. Para acessar um determinado banco de dados em nossa aplicação, geralmente utilizamos recursos como Conexões e adaptadores. Você está liberando estes recursos corretamente em sua aplicação? Dê uma olhada no código da Listagem 1.

 

Listagem 1. Exemplo de como NÃO liberar recursos corretamente

protected void Button1_Click(object sender, EventArgs e)

...

Quer ler esse conteúdo completo? Tenha acesso completo