2009-05-26 16 views
42

Estoy buscando una forma de rastrear las asignaciones de memoria en un programa C++. Estoy no interesado en fugas de memoria, que parecen ser lo que la mayoría de las herramientas están tratando de encontrar, sino en la creación de un perfil de uso de memoria para la aplicación. La salida ideal sería una gran lista de nombres de función más el número máximo de bytes asignados a lo largo del tiempo o mejor aún, una representación gráfica del montón a lo largo del tiempo. El eje horizontal es el tiempo, el espacio del montón del eje vertical. Cada función obtendría su propio color y dibujaría líneas de acuerdo con los bytes de montón asignados. Puntos de bonificación para identificar los tipos de objetos asignados también.seguimiento de las asignaciones de memoria C++

La idea es encontrar los cuellos de botella de la memoria/para visualizar qué funciones/hilos consumen la mayor cantidad de memoria y deben estar destinados a una mayor optimización.

Miré brevemente a Purify, BoundsChecker y AQ Time, pero no parecen ser lo que busco. Valgrind parece adecuado, sin embargo, estoy en Windows. Memtrack parece prometedor, pero requiere cambios significativos en el código fuente.

Mis habilidades de Google deben haberme fallado, porque no parece ser una solicitud tan poco común? Toda la información necesaria para crear una herramienta como esta debería estar disponible desde los símbolos de depuración del programa más las llamadas API en tiempo de ejecución, ¿no?

Respuesta

7

Monitoring Your PC's Memory Usage For Game Development contiene un casi perfecto ejemplo de lo que era buscando. Me tomó un tiempo ejecutarlo, pero el autor del artículo fue muy útil. Puede encontrar el código fuente de la herramienta aquí Memtracer.

También recibí muchas respuestas útiles en el SWENG (Lista de correo de ingeniería de software). El hilo se llama "[Sweng-Gamedev] monitoreando el uso de la memoria C++?".

17

Microsoft han documentado bien las funciones de seguimiento de memoria. Sin embargo, por alguna razón, no son muy conocidos en la comunidad de desarrolladores. Estas son funciones de depuración CRT. Un buen punto de partida será CRT Debug Heap functions.

Comprobar los siguientes enlaces para más detalles

  1. Heap state reporting functions
  2. Tracking heap allocation requests. Probablemente esta es la funcionalidad que está buscando.
+0

Sí, probablemente _CrtMemDumpAllObjectsSince es todo lo que está buscando. – stephan

27

Utilice Valgrind y su herramienta Massif. Su salida de ejemplo (una parte de ella):

99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. 
->49.74% (10,000B) 0x804841A: main (example.c:20) 
| 
->39.79% (8,000B) 0x80483C2: g (example.c:5) 
| ->19.90% (4,000B) 0x80483E2: f (example.c:11) 
| | ->19.90% (4,000B) 0x8048431: main (example.c:23) 
| | 
| ->19.90% (4,000B) 0x8048436: main (example.c:25) 
| 
->09.95% (2,000B) 0x80483DA: f (example.c:10) 
    ->09.95% (2,000B) 0x8048431: main (example.c:23) 

Así, obtendrá información detallada:

  • OMS asigna la memoria (funciones: g(), f(), y el principal() en el ejemplo anterior); usted también consigue traza completa que conduce a la función de asignación,
  • a la que la estructura de datos de la memoria fuimos (no hay estructuras de datos en el ejemplo anterior),
  • cuando sucedió,
  • qué porcentaje de toda la memoria asignada es (g : 39.7%, f: 9.95%, principal: 49.7%).

Aquí es Massif manual

Puede hacer un seguimiento asignación del montón, así como asignación de pila (desactivado por defecto).

PS. Acabo de leer que estás en Windows. Sin embargo, dejaré la respuesta porque da una idea de lo que puedes obtener de una posible herramienta.

+0

Massif no es compatible con multi-core y hace que el programa disminuya demasiado, ¿hay alguna otra herramienta que funcione con multi-core? – ZRJ

0

En Mac OS X, puede utilizar la herramienta de creación de perfiles de código Shark para hacerlo, IIRC.

12

Para un rastreador de memoria genérica de C++ tendrá que sobrecargar el siguiente:

global operator new 
global operator new [] 
global operator delete 
global operator delete [] 
any class allocators 
any in-place allocators 

El poco complicado es conseguir información útil, los operadores sobrecargados solamente tienen información para los asignadores de memoria y punteros para eliminaciones. Una respuesta es usar macros. Lo sé. Asqueroso. Un ejemplo - lugar en un encabezado que se incluye a todos los archivos de origen:

#undef new 

void *operator new (size_t size, char *file, int line, char *function); 
// other operators 

#define new new (__FILE__, __LINE__, __FUNCTION__) 

y crear un archivo fuente con:

void *operator new (size_t size, char *file, int line, char *function) 
{ 
    // add tracking code here... 
    return malloc (size); 
} 

Lo anterior sólo funciona si no tienen ningún nuevo operador definido en el alcance de la clase. Si usted tiene alguna al ámbito de clase, hacer:

#define NEW new (__FILE__, __LINE__, __FUNCTION__) 

y reemplazar 'nuevo tipo' con 'nuevo tipo', pero que requiere el cambio de una gran cantidad de código potencialmente.

Como se trata de una macro, eliminar el rastreador de memoria es bastante sencillo, la cabecera se convierte en:

#if defined ENABLED_MEMORY_TRACKER 
#undef new 

void *operator new (size_t size, char *file, int line, char *function); 
// other operators 

#define NEW new (__FILE__, __LINE__, __FUNCTION__) 
#else 
#define NEW new 
#endif 

y el archivo de implementación:

#if defined ENABLED_MEMORY_TRACKER 
void *operator new (size_t size, char *file, int line, char *function) 
{ 
    // add tracking code here... 
    return malloc (size); 
} 
endif 
0

En Xcode, puede usar instrumentos para rastrear asignaciones, uso de VM y muchos otros parámetros. Muy popular entre los desarrolladores de iOS, pero vale la pena intentarlo.

0

"Una representación gráfica del montón en el tiempo" - cerca de lo que está buscando se implementa en Intel(R) Single Event API, los detalles se pueden encontrar en this article (es bastante grande para ponerlo aquí). Memory block allocations over time

Muestra la línea de tiempo de las asignaciones por tamaño de bloque y permite agregar marcas adicionales a su código para comprender mejor la imagen completa.

Cuestiones relacionadas