La risposta breve a questa domanda è che nessuno di questi valori è un indicatore affidabile della quantità di memoria effettivamente utilizzata da un eseguibile e nessuno di essi è realmente appropriato per il debug di una perdita di memoria.
Byte privati si riferiscono alla quantità di memoria che l'eseguibile processo ha chiesto - non necessariamente la quantità è effettivamente utilizzando . Sono "privati" perché (di solito) escludono i file mappati in memoria (ovvero le DLL condivise). Ma - ecco il problema - non escludono necessariamente la memoria allocata da quei file . Non è possibile stabilire se una modifica dei byte privati sia dovuta all'eseguibile stesso o a una libreria collegata. Anche i byte privati non sono esclusivamente memoria fisica; possono essere paginati su disco o nell'elenco delle pagine di standby (ovvero non più in uso, ma non ancora cercati).
Il working set si riferisce alla memoria fisica totale (RAM) utilizzata dal processo. Tuttavia, a differenza dei byte privati, questo include anche file mappati in memoria e varie altre risorse, quindi è una misura ancora meno accurata dei byte privati. Questo è lo stesso valore che viene riportato in "Mem Usage" di Task Manager ed è stato fonte di infinite confusioni negli ultimi anni. La memoria nel Working Set è "fisica", nel senso che può essere indirizzata senza un errore di pagina; tuttavia, l'elenco delle pagine di attesa è anche ancora fisicamente in memoria, ma non riportato nel working set, e questo è il motivo per cui si potrebbe vedere la "Mem Usage" improvvisamente cadere quando si riduce a icona di un'applicazione.
I byte virtuali sono lo spazio degli indirizzi virtuali totali occupato dall'intero processo. Questo è come il set di lavoro, nel senso che include file mappati in memoria (DLL condivise), ma include anche i dati nell'elenco di standby e i dati che sono già stati pagati e si trovano in un file di paging sul disco da qualche parte. I byte virtuali totali utilizzati da ogni processo su un sistema sotto carico pesante si sommano a una quantità di memoria significativamente maggiore di quella effettivamente fornita dalla macchina.
Quindi le relazioni sono:
- I byte privati sono ciò che la tua app ha effettivamente allocato, ma includono l'utilizzo del file di paging;
- Il working set è costituito da byte privati non paginati più file mappati in memoria;
- I byte virtuali sono il working set più i byte privati paginati e l'elenco di standby.
C'è un altro problema qui; così come le librerie condivise possono allocare memoria all'interno del modulo dell'applicazione, portando a potenziali falsi positivi riportati nei Byte privati della tua app, l' applicazione potrebbe anche finire per allocare memoria all'interno dei moduli condivisi , portando a falsi negativi . Ciò significa che in realtà è possibile che l'applicazione presenti una perdita di memoria che non si manifesta mai nei byte privati. Improbabile, ma possibile.
I byte privati rappresentano un'approssimazione ragionevole della quantità di memoria utilizzata dall'eseguibile e possono essere utilizzati per aiutare a restringere un elenco di potenziali candidati per una perdita di memoria; se vedi che il numero cresce e cresce costantemente e all'infinito, vorresti controllare quel processo per individuare una perdita. Ciò, tuttavia, non può dimostrare che vi sia o meno una perdita.
Uno degli strumenti più efficaci per rilevare / correggere le perdite di memoria in Windows è in realtà Visual Studio (il collegamento va alla pagina sull'utilizzo di VS per le perdite di memoria, non la pagina del prodotto). Rational Purify è un'altra possibilità. Microsoft ha anche un documento di best practice più generale su questo argomento. Ci sono più strumenti elencati in questa domanda precedente .
Spero che questo chiarisca alcune cose! Rilevare perdite di memoria è una delle cose più difficili da fare nel debug. In bocca al lupo.