Compartir a través de


Evitar fugas de memoria en aplicaciones Windows

Plataformas afectadas

Clientes : Windows 7
Servidores : Windows Server 2008 R2

Descripción

Las fugas de memoria son una clase de errores en los que la aplicación no puede liberar memoria cuando ya no es necesario. Con el tiempo, las pérdidas de memoria afectan al rendimiento de la aplicación en particular, así como al sistema operativo. Una fuga grande podría dar lugar a tiempos de respuesta inaceptables debido a una paginación excesiva. Finalmente, la aplicación, así como otras partes del sistema operativo, experimentarán errores.

Windows liberará toda la memoria asignada por la aplicación al finalizar el proceso, por lo que las aplicaciones de ejecución corta no afectarán significativamente al rendimiento general del sistema. Sin embargo, las fugas en procesos de larga duración, como servicios o incluso complementos del Explorador, pueden afectar considerablemente a la confiabilidad del sistema y podría forzar al usuario a reiniciar Windows para poder volver a usar el sistema.

Las aplicaciones pueden asignar memoria en su nombre por varios medios. Cada tipo de asignación puede producir una fuga si no se libera después de su uso. Estos son algunos ejemplos de patrones de asignación comunes:

  • Memoria del montón a través de la función HeapAlloc o sus equivalentes en tiempo de ejecución de C/C++ malloc o nuevos
  • Asignaciones directas desde el sistema operativo a través de la función VirtualAlloc .
  • Los identificadores de kernel creados a través de las API de Kernel32, como CreateFile, CreateEvent o CreateThread, contienen la memoria del kernel en nombre de la aplicación.
  • Identificadores GDI y USER creados a través de las API de User32 y Gdi32 (de forma predeterminada, cada proceso tiene una cuota de 10 000 identificadores)

Prácticas recomendadas

La supervisión del consumo de recursos de la aplicación a lo largo del tiempo es el primer paso para detectar y diagnosticar pérdidas de memoria. Use el Administrador de tareas de Windows y agregue las columnas siguientes: "Commit Size", "Handles", "User Objects" y "GDI Objects". Esto le permitirá establecer una línea base para la aplicación y supervisar el uso de recursos a lo largo del tiempo.

Captura de pantalla que muestra la página

Las siguientes herramientas de Microsoft proporcionan información más detallada y pueden ayudar a detectar y diagnosticar fugas para los distintos tipos de asignación de la aplicación:

  • Monitor de rendimiento y Resource Monitor forman parte de Windows 7 y pueden supervisar y grafo el uso de recursos a lo largo del tiempo
  • La versión más reciente de Application Verifier puede diagnosticar pérdidas de montón en Windows 7
  • UMDH, que forma parte de las herramientas de depuración para Windows, analiza las asignaciones de memoria del montón para un proceso determinado y puede ayudar a encontrar fugas y otros patrones de uso inusuales.
  • Xperf es una herramienta de análisis de rendimiento sofisticada con compatibilidad con seguimientos de asignación de montón.
  • El montón de depuración de CRT realiza un seguimiento de las asignaciones del montón y puede ayudar a crear sus propias características de depuración de montón.

Ciertas prácticas de codificación y diseño pueden limitar el número de fugas en el código.

  • Use punteros inteligentes en código de C++ tanto para asignaciones de montón como para recursos de Win32, como HANDLEdel kernel. La biblioteca estándar de C++ proporciona la clase auto_ptr para las asignaciones del montón. Para otros tipos de asignación, deberá escribir sus propias clases. La biblioteca ATL proporciona un amplio conjunto de clases para la administración automática de recursos para los objetos del montón y los identificadores de kernel.
  • Use características intrínsecas del compilador como _com_ptr_t para encapsular los punteros de interfaz COM en "punteros inteligentes" y ayudar con el recuento de referencias. Hay clases similares para otros tipos de datos COM: _bstr_t y _variant_t
  • Supervise el uso inusual de memoria del código de .NET. El código administrado no es inmune a las pérdidas de memoria. Consulte "Seguimiento de pérdidas de memoria administrada" sobre cómo buscar fugas de GC.
  • Tenga en cuenta los patrones de fuga en el código del lado cliente web. Las referencias circulares entre objetos COM y motores de scripting como JScript pueden provocar fugas grandes en aplicaciones web. "Descripción y resolución de patrones de fuga de Internet Explorer" tiene más información sobre estos tipos de fugas. Puede usar el Detector de fugas de memoria de JavaScript para depurar pérdidas de memoria en el código. Aunque Windows Internet Explorer 8, que se envía con Windows 7, mitiga la mayoría de estos problemas, los exploradores más antiguos siguen siendo vulnerables a estos errores.
  • Evite el uso de varias rutas de acceso de salida desde una función. Las asignaciones asignadas a variables en el ámbito de función deben liberarse en un bloque determinado al final de la función.
  • No use excepciones en el código sin liberar todas las variables locales en las funciones. Si usa excepciones nativas, libere todas las asignaciones dentro del bloque __finally. Si usa excepciones de C++, todas las asignaciones de montón y control deben encapsularse en punteros inteligentes.
  • No descarte ni reinicialice un objeto PROPVARIANT sin llamar a la función PropVariantClear

Patrones de asignación comunes:

Herramientas de Microsoft:

Vínculos adicionales: