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.
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
Links para recursos
Padrões comuns de alocação:
- Função de alocação de heap
- Função alocação de memória
- Novo operador (C++)
- Função de alocação virtual
- Objetos Kernel
- Identificadores de objeto GDI
- Identificadores de objeto de interface do usuário
Ferramentas da Microsoft:
- Verificador de Aplicativos
- Ferramentas de Depuração para Windows
- Heap de despejo no modo de usuário
- Ferramenta de Captura, Processamento e Análise de Rastreamento
- Heap de Depuração do CRT
Links adicionais:
- Classe auto_ptr
- Classes de memória da ATL (Biblioteca de Modelos Ativos)
- Objeto _com_ptr_t
- Classe _bstr_t
- Classe _variant_yt
- "Como rastrear vazamentos de memória gerenciada"
- "Noções básicas e resolução de padrões de vazamento de Explorer da Internet"
- "Detector de Vazamento de Memória JavaScript"
- Mitigação de Vazamento de Memória Circular (em navegadores):
- Instrução try-finally
- Estrutura PROPVARIANT
- Função PropVariantClear