2012-05-02 10 views
8

Un mio collega è convinto che ci sia una perdita di memoria nell'implementazione di odod.net ado.net di Oracle. Ha scritto un programma di test per testare questa teoria e sta facendo quanto segue dopo aver chiamato smaltire su ogni oggetto al fine di determinare la quantità di memoria viene liberata:GC.Collect() e PerformanceCounter

PerformanceCounter p = new PerformanceCounter("Memory", "Available Bytes"); 

GC.Collect(); 
GC.WaitForPendingFinalizers(); 

float mem = p.NextValue(); 

Il valore delle prestazioni risultante viene poi confrontato con un valore recuperato prima di smaltire l'oggetto. Ciò produrrà risultati accurati?

+10

No, non è così che funziona il gestore della memoria. Dopo aver passato il problema dell'allocazione dello spazio di memoria virtuale, rimette i blocchi rilasciati nuovamente nella lista dei blocchi liberi, pronti per essere riutilizzati più tardi. –

+0

Hai provato a utilizzare ProcessExplorer per monitorare l'utilizzo della memoria e della memoria di sistema di .NET all'interno del processo? Non hai specificato quale tipo di memoria perde ... – GregC

+0

Non sappiamo quale tipo di memoria perde, questo è parte del motivo del test, per confermare che c'è un problema. La mia domanda è di confermare se il test è valido. – zaq

risposta

2

Penso che il modo migliore per farlo è utilizzare GC.GetTotalMemory(true). È possibile chiamarlo prima di allocare l'oggetto per registrare la quantità di memoria allocata. Quindi crei il tuo oggetto, magari esegui qualche operazione su di esso, disponilo, assicurati che non ci siano riferimenti (probabilmente solo impostando la variabile locale su null) e poi richiamalo.

Tenere in potenza che il valore restituito potrebbe non essere completamente esatto, per la documentazione, il metodo ritorna:

Un numero che è la migliore approssimazione disponibile del numero di byte attualmente allocato nella memoria gestita .

Successivamente, è possibile confrontare i due valori. Se lo fai ripetutamente, puoi vedere se l'oggetto sta effettivamente perdendo la memoria gestita.

Ovviamente, questo non è di aiuto se l'oggetto perde memoria non gestita.

Un'altra opzione consiste nell'utilizzare un profiler di memoria, ma potrebbe essere eccessivo se si sa esattamente dove la memoria potrebbe fuoriuscire.

+0

Grazie per l'idea su come ottenere risultati migliori. Questo significa che c'è qualcosa di sbagliato nell'approccio che ho postato? Perché questo è un approccio migliore? – zaq

+2

Sì, il tuo approccio è sbagliato, leggi il commento di Hans Passant. Quando il CLR raccoglie garbage, di solito non restituisce la memoria al sistema, quindi potresti non vedere alcuna modifica in Byte disponibili, anche se la memoria è stata effettivamente liberata. – svick

Problemi correlati