2009-05-26 13 views
42

Sto cercando un modo per tenere traccia delle allocazioni di memoria in un programma C++. Sono non interessato a perdite di memoria, che sembrano essere ciò che la maggior parte degli strumenti sta tentando di trovare, ma piuttosto creare un profilo di utilizzo della memoria per l'applicazione. L'output ideale potrebbe essere una lunga lista di nomi di funzioni più il numero di byte allocati massimi nel tempo o, meglio ancora, una rappresentazione grafica dell'heap nel tempo. L'asse orizzontale è il tempo, lo spazio heap dell'asse verticale. Ogni funzione ottiene il proprio colore e traccia le linee in base ai byte heap allocati. Punti bonus per identificare anche i tipi di oggetti assegnati.traccia allocazioni memoria C++

L'idea è di trovare i colli di bottiglia della memoria/per visualizzare quali funzioni/thread consumano più memoria e dovrebbero essere mirate per un'ulteriore ottimizzazione.

Ho dato una breve occhiata a Purify, BoundsChecker e AQTime ma non sembrano essere quello che sto cercando. Valgrind sembra adatto, tuttavia, io sono su Windows. Memtrack sembra promettente, ma richiede modifiche significative al codice sorgente.

Le mie competenze di google devono avermi fallito, perché non sembra essere una richiesta così insolita? Tutte le informazioni necessarie per creare uno strumento come questo dovrebbero essere prontamente disponibili dai simboli di debug del programma più le chiamate all'API di runtime - no?

risposta

7

Monitoring Your PC's Memory Usage For Game Development contiene un quasi perfetto esempio di quello che ero cercando. Ci è voluto un po 'per farlo funzionare, ma l'autore dell'articolo è stato molto utile. È possibile trovare il codice sorgente per lo strumento qui Memtracer.

Ho anche ricevuto molte risposte utili su SWENG (Lista di distribuzione di software engineering). Il thread è chiamato "[Sweng-Gamedev] che monitora l'utilizzo della memoria C++?".

17

Microsoft sono ben documentati funzioni di tracking di memoria. Tuttavia, per qualche motivo non sono molto conosciuti nella comunità degli sviluppatori. Queste sono funzioni di debug CRT. Il buon punto di partenza sarà CRT Debug Heap functions.

controllare i seguenti link per ulteriori dettagli

  1. Heap state reporting functions
  2. Tracking heap allocation requests. Probabilmente questa è la funzionalità che stai cercando.
+0

Sì, probabilmente _CrtMemDumpAllObjectsSince è tutto ciò che sta cercando. – stephan

27

Utilizzare Valgrind e il suo strumento Massif. La sua uscita esempio (una parte di esso):

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) 

Così, si ottengono informazioni dettagliate:

  • OMS allocata la memoria (funzioni: g(), f(), e main() nell'esempio sopra); si ottiene anche completa backtrace che porta alla funzione di allocazione,
  • alla quale struttura di dati nella memoria è andata (no strutture dati in esempio di cui sopra),
  • quando è successo,
  • quale percentuale di tutta la memoria allocata che è (g : 39,7%, f: 9,95%, principale: 49,7%).

Ecco Massif manual

È possibile tenere traccia di allocazione heap e stack di allocazione (disattivata per impostazione predefinita).

PS. Ho appena letto che sei su Windows. Lascerò comunque la risposta, perché fornisce un'immagine di ciò che è possibile ottenere da uno strumento possibile.

+0

Massif non supporta il multi-core e rallenta eccessivamente il programma, c'è qualche altro strumento che funziona con multi-core? – ZRJ

0

Su Mac OS X, è possibile utilizzare lo strumento di profiling del codice Shark per eseguire questa operazione, IIRC.

12

Per un tracker generico C++ memoria è necessario sovraccaricare il seguente:

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

La parte difficile è ottenere informazioni utili, gli operatori di overload hanno solo informazioni di dimensione per allocatori e puntatori di memoria per le eliminazioni. Una risposta è usare le macro. Lo so. Cattiva. Un esempio - posto in un colpo di testa che è incluso da tutte le file di origine:

#undef new 

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

#define new new (__FILE__, __LINE__, __FUNCTION__) 

e creare un file di origine con:

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

È possibile che questo funziona solo se non hanno alcun operatore di nuovo definito allo scopo di classe. Se avete un po 'a portata di classe, fare:

#define NEW new (__FILE__, __LINE__, __FUNCTION__) 

e sostituire 'nuovo tipo di' con 'NEW Tipo', ma che richiede la modifica di un sacco di codice potenzialmente.

Come è un macro, rimuovendo il tracker di memoria è molto semplice, l'intestazione diventa:

#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 

e file di implementazione:

#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

Su Xcode, è possibile utilizzare gli strumenti per tenere traccia di allocazioni, utilizzo della VM e diversi altri parametri. Molto popolare tra gli sviluppatori iOS, ma vale la pena provare.

0

"Una rappresentazione grafica dell'heap nel tempo" - vicino a ciò che si sta cercando è implementato in Intel(R) Single Event API, i dettagli possono essere trovati in this article (è piuttosto grande per metterlo qui). Memory block allocations over time

Mostra la cronologia delle allocazioni per blocco e consente di aggiungere ulteriore contrassegno al codice per comprendere meglio l'intera immagine.

Problemi correlati