2009-11-08 8 views

Respuesta

2

Una solución especulativa: redefinir new y delete operadores.

En cada llamada de operador new, se pasa una cantidad de bytes para asignar. Asigne un poco más de memoria y almacene la cantidad de bytes asignados dentro. Agregue esta cantidad a la variable global que contiene el tamaño del montón.

En la llamada de operador delete, compruebe el valor almacenado antes de deshacerse de la memoria. Restarlo de esa variable global.

0

Aparte de hacer el seguimiento de todas sus asignaciones de memoria que no creo que hay una manera de calcular el tamaño de la pila o el uso

3

No es fácil, automática forma de hacerlo, si eso es lo que está preguntando. Básicamente, debe realizar un seguimiento manual de las asignaciones de montón usted mismo utilizando una variable de contador. El problema es que es difícil controlar qué partes de tu programa están asignando memoria en el montón, especialmente si estás usando muchas bibliotecas fuera de tu control. Para complicar aún más las cosas, hay dos maneras en que un programa puede asignar memoria de pila: new o malloc. (Sin mencionar las llamadas directas al sistema operativo como sbrk.)

Puede override global operator new, y cada llamada a un nuevo aumento de un conteo global. Sin embargo, esto no incluirá necesariamente los momentos en que su programa llame al malloc, o cuando su programa utilice una anulación de clase específica new. También puede anular malloc usando una macro, pero esto no es necesariamente portátil. Y también tendría que anular todas las variaciones de malloc, como realloc, calloc, etc. Todo esto se complica aún más por el hecho de que en algunas implementaciones, el propio new puede llamar al new.

Por lo tanto, esencialmente, es muy difícil hacerlo correctamente desde dentro de su programa. Recomiendo usar una herramienta de memoria de perfil en su lugar.

6

Existen varias posibilidades.

¿Qué precisión necesita que sea? Puede obtener algunos datos útiles a través del cat/proc/$ {PID}/status | grep VmData.

Puede #define su propio malloc(), realloc(), calloc(), y libres() funciones, que envuelven las funciones reales detrás de su propio contador. Aquí puede hacer cosas geniales con __FILE__, __LINE__, & __func__ para facilitar la identificación de fugas en las pruebas simples. ¡Pero solo instrumentará su propio código!

(Del mismo modo, también se puede redefinir el valor predeterminado operador nueva y operador borrar métodos, las dos variantes de matriz y no de la matriz, y las dos variantes que lanzan std :: bad_alloc y std :: nothrow_t. Una vez más, esto será único instrumento de su propio código)

(tenga en cuenta: en la mayoría de los sistemas de C++, nueva en última instancia invoca malloc()!.. no tiene a Especialmente con en-pl as nuevo! Pero típicamente nuevo hace uso de malloc(). (O que opera en una región de la memoria que ha sido previamente malloc() 'ed.) De lo contrario se obtendría en cosas muy a la moda con múltiples administradores de pila ...)

Usted puede utilizar sbrk (0) para ver dónde se encuentra actualmente el segmento de datos. Eso no es tan bueno. Es una medida muy aproximada, y no tiene en cuenta los agujeros (regiones de memoria no utilizadas) en el montón. (Es mucho mejor con la línea deVmData de /proc/PID $ {}/estado.) Pero si sólo estás buscando una idea general ...

Puede interceptar malloc()/free()/etc escribiendo su propia biblioteca compartida y forzando su proceso para usarla en lugar de las versiones reales a través de LD_PRELOAD. Puede usar dlopen()/dlsym() para cargar & invocar el * real * malloc()/free()/etc. Esto funciona bastante bien. El código original no está modificado, ni siquiera recompilado. Pero tenga en cuenta las situaciones de reentrada al codificar esta biblioteca y su proceso invocará inicialmente malloc()/calloc()/realloc() antes de dlopen()/dlsym() puede completar la carga de las funciones reales.

Puede echar un vistazo a herramientas como Valgrind, aunque eso realmente apunta más a fugas de memoria.


Por otra parte, tal vez mtrace() es lo que quieres? O __malloc_hook? Muy propietario (GNU) & no estándar ... Pero está etiquetado como "Linux" ...

1

Dado que ha etiquetado su pregunta 'linux', puede ser útil ver algo de la información proporcionada en el directorio /proc. No he investigado mucho esto, así que solo puedo darte un punto de partida.

/proc/<your programs pid> contiene archivos con información sobre su proceso desde el punto de vista del kernel. Hay un enlace simbólico /proc/self que siempre informará acerca del proceso de su investigación.

Los archivos que más le pueden interesar son stat, statm y status. Este último es más legible por humanos, mientras que los dos anteriores brindan la misma información en un formato más legible por máquina.

Un punto de partida sobre cómo interpretar el contenido de esos archivos está disponible en la página de manual proc(5).

6

creo mallinfo() es lo que quiere: Estructura mallinfo

#include <malloc.h> 


struct mallinfo *info; 

info = mallinfo(); 

printf ("total allocated space: %llu bytes\n", info->uordblks); 
printf ("total free space:  %llu bytes\n", info->fordblks); 

La estructura es de carácter técnico y específico para la implementación de malloc(). Pero la información que desea está ahí. Aquí es cómo puedo informar de los valores:

mallinfo.arena = "Total Size (bytes)" 
mallinfo.uordblks = "Busy size (bytes)" 
mallinfo.fordblks = "Free size (bytes)" 
mallinfo.ordblks = "Free blocks (count)" 
mallinfo.keepcost = "Top block size (bytes)" 
mallinfo.hblks = "Blocks mapped via mmap() (count)" 
mallinfo.hblkhd = "Bytes mapped via mmap() (bytes)" 

Estos dos son supuestamente no se utiliza, pero parece que cambiar en mi sistema, y ​​por lo tanto podría ser válida:

mallinfo.smblks = "Fast bin blocks (count)" 
mallinfo.fsmblks = "Fast bin bytes (bytes)" 

Y el otro valor interesante es devuelto por "sbrk (0)"

+0

Parece obsoleto o no es útil en 2017 para máquinas de 64 bits, para memoria asignada mayor que 2 GB :( – Makesh

Cuestiones relacionadas