2010-02-05 14 views
5

Una aplicación que estoy trabajando con está exhibiendo el comportamiento siguiente:¿Alguna sugerencia útil para descubrir dónde se libera la memoria en un proceso de Win32?

  1. Durante una operación de alta de memoria en particular, el uso de memoria del proceso en el Administrador de tareas (Mem Uso stat) alcanza un máximo de aproximadamente 2.5GB (Nota: Se ha configurado una clave de registro para permitir esto, ya que normalmente hay un máximo de 2 GB para un proceso en Windows de 32 bits)

  2. Después de que se completa la operación, el tamaño del proceso comienza a disminuir lentamente en una tasa de 1MB por segundo.

Estoy tratando de encontrar la manera más fácil de determinar rápidamente quién está liberando esta memoria y dónde se está liberando.

Tengo problemas para conectar un generador de perfiles de memoria para mi código, y yo no quiero particularmente para anular los new/delete operadores para realizar un seguimiento de las asignaciones/cancelaciones de asignación (OIA, quiero hacer esto sin volver a compilar el código)

¿Alguien puede ofrecer alguna sugerencia útil de cómo podría hacer esto a través del depurador de Visual Studio?


actualización

También debo mencionar que es una aplicación multi-hilo, por lo que la pausa de la aplicación y el análisis de la pila de llamadas a través del depurador no es la opción más deseable. Consideré congelar diferentes hilos de a uno por vez para ver si la memoria deja de reducirse, pero estoy bastante seguro de que esto hará que la aplicación falle.

+0

Qué perfiles ha probado. Es caro, pero he utilizado el comprobador de límites antes para resolver problemas de memoria aparentemente intratables. – rerun

+2

Puede intentar establecer un punto de interrupción en la función de eliminación del tiempo de ejecución.Una forma de llegar: en la parte superior de la línea principal, simplemente haga 'int * i = new int; eliminar i; '. Siga este paso y entre en la línea 'delete i'; debería terminar en la función de eliminación de tiempo de ejecución. Ahora ponga un punto de interrupción allí, (elimine el código int) y ejecute su programa. Cuando tu memoria comience a liberarse, podrás verificar la pila. No voy a poner esto como una respuesta todavía, porque no estoy seguro si esto es lo que estás pidiendo. – GManNickG

+0

@rerun - Usamos Rational Purify, pero no he probado el comprobador de límites. @GMan - Buena idea; Voy a dar una oportunidad. – LeopardSkinPillBoxHat

Respuesta

2

¡Ahh! ¡Estás mirando el mostrador equivocado!

Mem Usage no te dice que se está liberando memoria. ¡Solo que el conjunto de trabajo está siendo purgado! Esto podría significar que alguna otra aplicación necesita memoria, o el VMM decidió marcar algunas de las páginas de su proceso como En espera para que otro proceso lo use rápidamente. No significa que se está llamando a VirtualFree, HeapFree o cualquier otra función gratuita.

Mira el tamaño de confirmación (Tamaño VM, Bytes privados, etc.).

Pero si aún desea saber cuándo se está liberando o liberando memoria o qué es lo que tiene, interrumpa algunas llamadas gratuitas. P.ej. (Para Visual C++)

{,,kernel32.dll}HeapFree 

o

{,,msvcr80.dll}free 

etc.

O simplemente un punto de interrupción función regular en lo anterior. Solo asegúrate de que resuelva la dirección.

CDB/WinDBG dejar que lo hace a través de

bp kernel32!HeapFree 
bp msvcrt!free 

etc.

nombres pueden variar dependiendo de la versión que utiliza y cómo se vincula CRT en contra de ella (a través de /MT o /MD y sus variantes)

0

Un par de ideas diferentes:

  • El tiempo de ejecución de C tiene un conjunto de funciones de depuración de memoria; necesitarías recompilar sin embargo. Puede obtener una instantánea al completar el cálculo y más tarde, y usar _CrtMemDifference para ver qué cambió.

  • O bien, puede conectarlo al proceso en su depurador y hacer que descargue un núcleo antes y después de liberar la memoria. Usando NTSD, puedes ver qué montones están alrededor, y el tamaño de las cosas. (Necesitará mucho espacio en disco y mucha paciencia.) Hay una configuración (creo que se obtiene a través de gflags, pero no recuerdo) que hace que guarde una parte de la pila de llamadas como parte del vertedero; usando eso puedes averiguar qué tipo de objeto se está desasignando. Desafortunadamente, solo almacena 4 o 5 fotogramas de pila, por lo que es probable que tengas que hacer algo más inteligente como el siguiente paso para descubrir dónde se libera. Observe el código ("oh, sí, solo hay un lugar donde eso puede suceder") o ponga puntos de corte en esos destructores, o agregue el rastreo a las asignaciones y desasignaciones.

0

Si su administrador de memoria borra los datos free'd a un valor conocido (generalmente algo como 0xfeeefeee), se puede establecer un punto de interrupción de datos en una instancia particular de algo que le interesa.Cuando se libera, el punto de interrupción se disparará cuando se borre la memoria.

0

Le recomiendo que compruebe la herramienta UMDH que viene con Debugging Tools For Windows (Puede encontrar ejemplos de uso y ejemplos en la herramienta de depuración). Puede ajustar las asignaciones de montón del proceso de ejecución de instantáneas con el seguimiento de pila y compararlas.

0

Usted podría intentar Memory Validator para monitorear las asignaciones y cancelaciones de asignación. Validador de memoria tiene un par de características que le ayudarán a identificar dónde se cancela la asignación de datos:

  • Hotspots vista. Esto puede mostrarle un árbol de todas las asignaciones y desasignaciones o solo todas las asignaciones o simplemente todas las desasignaciones. Presenta los datos como un porcentaje de la actividad de la memoria (según la cantidad de memoria (de) asignada en una ubicación determinada).

  • Vista de análisis. Puede realizar consultas que soliciten datos en un rango de direcciones dado. Puede restringir estas consultas a cualquiera de los comportamientos alloc, realloc, dealloc.

  • Objetos vista. Puede ver las asignaciones por tipo y ver la cantidad máxima de objetos de cada tipo (más muchas otras estadísticas). Haga clic con el botón derecho en un tipo para obtener un menú contextual, elija mostrar todas las desasignaciones: mostrará las ubicaciones de desasignación para ese tipo en la pestaña Análisis.

Creo que la vista de Hotspots puede darle la información que necesita.

Cuestiones relacionadas