Compartilhar via


Prevenção de vazamentos de memória em aplicativos do Windows

Plataformas afetadas

Clientes – Windows 7
Servidores – Windows Server 2008 R2

Descrição

Vazamentos de memória são uma classe de bugs em que o aplicativo não libera memória quando não é mais necessário. Com o tempo, os vazamentos de memória afetam o desempenho do aplicativo específico, bem como do sistema operacional. Um grande vazamento pode resultar em tempos de resposta inaceitáveis devido a paginação excessiva. Eventualmente, o aplicativo, bem como outras partes do sistema operacional, sofrerão falhas.

O Windows liberará toda a memória alocada pelo aplicativo no encerramento do processo, portanto, aplicativos de execução curta não afetarão significativamente o desempenho geral do sistema. No entanto, vazamentos em processos de longa execução, como serviços ou até mesmo plug-ins Explorer, podem afetar muito a confiabilidade do sistema e podem forçar o usuário a reinicializar o Windows para tornar o sistema utilizável novamente.

Os aplicativos podem alocar memória em seu nome por vários meios. Cada tipo de alocação pode resultar em um vazamento se não for liberado após o uso. Aqui estão alguns exemplos de padrões comuns de alocação:

  • Memória de heap por meio da função HeapAlloc ou seus equivalentes de runtime C/C++ malloc ou novo
  • Alocações diretas do sistema operacional por meio da função VirtualAlloc .
  • Identificadores de kernel criados por meio de APIs kernel32, como CreateFile, CreateEvent ou CreateThread, mantêm a memória do kernel em nome do aplicativo
  • Identificadores GDI e USER criados por meio de APIs User32 e Gdi32 (por padrão, cada processo tem uma cota de 10.000 identificadores)

Práticas Recomendadas

Monitorar o consumo de recursos do aplicativo ao longo do tempo é a primeira etapa para detectar e diagnosticar vazamentos de memória. Use o Gerenciador de Tarefas do Windows e adicione as seguintes colunas: "Tamanho da confirmação", "Identificadores", "Objetos de Usuário" e "Objetos GDI". Isso permitirá que você estabeleça uma linha de base para seu aplicativo e monitore o uso de recursos ao longo do tempo.

Captura de tela que mostra a página 'Processos' no Gerenciador de Tarefas do Windows.

As seguintes ferramentas da Microsoft fornecem informações mais detalhadas e podem ajudar a detectar e diagnosticar vazamentos para os vários tipos de alocação em seu aplicativo:

  • Monitor de Desempenho e o Resource Monitor fazem parte do Windows 7 e podem monitorar e grafar o uso de recursos ao longo do tempo
  • A versão mais recente do Verificador de Aplicativos pode diagnosticar vazamentos de heap no Windows 7
  • O UMDH, que faz parte das Ferramentas de Depuração para Windows, analisa as alocações de memória de heap para um determinado processo e pode ajudar a encontrar vazamentos e outros padrões de uso incomuns
  • O Xperf é uma ferramenta sofisticada de análise de desempenho com suporte para rastreamentos de alocação de heap
  • O Heap de Depuração do CRT rastreia alocações de heap e pode ajudar a criar seus próprios recursos de depuração de heap

Determinadas práticas de codificação e design podem limitar o número de vazamentos em seu código.

  • Use ponteiros inteligentes no código C++ tanto para alocações de heap quanto para recursos do Win32, como handlesde kernel. A biblioteca C++ Standard fornece a classe auto_ptr para alocações de heap. Para outros tipos de alocação, você precisará escrever suas próprias classes. A biblioteca ATL fornece um conjunto avançado de classes para gerenciamento automático de recursos para objetos heap e identificadores de kernel
  • Use recursos intrínsecos do compilador, como _com_ptr_t , para encapsular os ponteiros da interface COM em "ponteiros inteligentes" e auxiliar na contagem de referências. Há classes semelhantes para outros tipos de dados COM: _bstr_t e _variant_t
  • Monitore o uso incomum de memória do código .NET. O código gerenciado não é imune a vazamentos de memória. Confira "Como rastrear vazamentos de memória gerenciada" sobre como encontrar vazamentos de GC
  • Esteja ciente dos padrões de vazamento no código do lado do cliente web. Referências circulares entre objetos COM e mecanismos de script, como JScript, podem causar grandes vazamentos em aplicativos Web. "Noções básicas e resolução de padrões de vazamento de Explorer da Internet" tem mais informações sobre esses tipos de vazamentos. Você pode usar o Detector de Vazamento de Memória JavaScript para depurar vazamentos de memória em seu código. Embora o Windows Internet Explorer 8, que está sendo enviado com o Windows 7, reduza a maioria desses problemas, os navegadores mais antigos ainda são vulneráveis a esses bugs
  • Evite usar vários caminhos de saída de uma função. As alocações atribuídas a variáveis no escopo da função devem ser liberadas em um bloco específico no final da função
  • Não use exceções em seu código sem liberar todas as variáveis locais em funções. Se você usar exceções nativas, libere todas as alocações dentro do bloco __finally. Se você usar exceções C++, todas as alocações de heap e identificador precisarão ser encapsuladas em ponteiros inteligentes
  • Não descarte nem reinicialize um objeto PROPVARIANT sem chamar a função PropVariantClear

Padrões comuns de alocação:

Ferramentas da Microsoft:

Links adicionais: