2009-07-24 11 views
6

La mia app utilizzava 150mb di memoria non molto tempo fa, ora è a 286mb. Si alza lentamente, quindi devo dimenticarmi di smaltire qualcosa. Questo non è un problema per me dato che ho 4 GB, ma voglio mandarlo ad altri che hanno solo 1 GB di RAM. altro poi passando attraverso il codice riga per riga come posso trovare oggetti che devono essere eliminati o solo oggetti generalmente di grandi dimensioni?Come trovare problemi di smaltimento e di memoria? C#

risposta

2

Controlla il .NET Memory Profiler. C'è una prova di 15 giorni e vale la pena pagare la licenza.

identificare facilmente le perdite di memoria da raccolta e il confronto istantanee di istantanee di memoria .NET includono dati su .NET istanze allocazioni e le istanze in scena a tempo l'istantanea è stato raccolto. Forniscono un sacco di informazioni utili e lo rendono facile identificare potenziali perdite di memoria , in particolare quando vengono confrontate due istantanee .

1

È anche possibile utilizzare WinDbg e SOS. Questi hanno il vantaggio di essere liberi e molto, molto accurati, anche se un po 'difficili da abituare.

Ecco un blog post che descrive il processo.

+2

windbg e SOS sono anche i miei preferiti. C'è un post più vecchio sul blog di Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx –

+0

Questo è stato il post che mi ha fatto innamorare di SOS in origine ... Ma quello che ho postato penso sia un po 'più facile da seguire. –

4

Estensione di entrambe le risposte di JP e Reed.

Volevo chiarire un po 'di confusione. Se si riscontrano significativi aumenti di memoria, è improbabile che il problema sia un problema con la chiamata a Dispose. Dispose viene in genere utilizzato per liberare risorse non gestite come gli handle. Questi non occupano molta memoria, ma invece sono più preziosi come risorse.

Gli incrementi di memoria sono generalmente associati a oggetti di grandi dimensioni o raccolte accessibili da un oggetto gestito che viene radicato direttamente o indirettamente tramite un oggetto stack o un handle GC avanzato. Questa è l'area su cui probabilmente concentrerai le tue indagini.

+0

Sì, questo è un grande punto. Uso il profiler di memoria per realizzare cose del tipo "oh, quella collezione non dovrebbe diventare sempre più grande per sempre!" :) –

+2

Inoltre, dai un'occhiata agli eventi a cui sei iscritto. L'evento contiene un riferimento al sottoscrittore e, se non si annulla mai, tale riferimento non viene mai rimosso. – JulianR

0

Partenza this link

Stephen Toub va in grande lunghezza per spiegare le varie tecniche per fare questo, Seguono alcuni brevi punti salienti del suo articolo

  • Con l'aggiunta di un finalizzatore a scopo di debug, è possibile introdurre un modo per scoprire quando una classe non è stata correttamente disposta, se il finalizzatore non viene mai chiamato, si kno w che smaltiti non è stato chiamato

  • Per ottenere ulteriori informazioni sul caso, threadIds ecc per aiutare a restringere il quale istanza non ha avuto è smaltito invocato, si crea una classe FinalizationDebgger che la classe e getta sarebbe tieni premuto su quale di questi passi chiama il Dispose dell'istanza della classe FinalizationDebugger quando è di sua proprietà. Se Dispose non viene chiamato sul l'istanza della classe poi quando Finalizer gestisce richiamerà il finalizzatore per esempio FinalizationDebgger dove si poteva far valere o un'eccezione per aiutare il debug il problema,

  • Spostare tutto il tracking codice correlato in una classe base che la classe usa e getta avrebbe ereditato da , il che rende il codice molto più pulito. Questo approccio può o non può funzionare dato che si masterizza una classe base e se si eredita già da un'altra base.

  • Nell'ultima opzione tutto viene scomposto in una classe statica a cui si richiamano le istanze . FinalizationDebugger diventa una classe statica che espone tre metodi statici : Constructor, Dispose e Finalizer. L'idea è che chiami questi metodi dalla posizione appropriata nella tua classe (dispose/finalize/constructor). Questo è minimamente invasivo nel tuo codice, poiché in genere comporta l'aggiunta di sole tre righe di codice. Tutti gli di questi metodi sono contrassegnati con un ConditionalAttribute tale che verranno chiamati solo dalla classe quando si compila la classe in modalità DEBUG.

Stephen spiega anche i pro e i contro di ciascuno dei suoi approcci. Le soluzioni presentano varie opzioni e dovresti valutare ognuna per capire quale funziona meglio per la tua situazione. A DEVE leggere IMHO

Spero che questo aiuti.

+0

È necessario compilare la risposta per alzare i voti. Il solo puntamento a un link non è abbastanza buono, perché se il link va don non è più una risposta utile. –

+0

Abbastanza corretto, modificare la risposta per includere un breve riepilogo di ciò che è coperto nell'articolo MSDN –

0

Prova anche ANTS Memory Profiler. C'è una prova gratuita di 14 giorni completamente funzionante, e mi piace molto l'interfaccia utente.

Disclosure: sponsorizzano il Codice Herding in questo momento, motivo per cui l'ho provato. Ma ne sono davvero impressionato - ho profilato un'applicazione per 30 ore e ne ho ricavato tonnellate di informazioni utili. L'interfaccia utente è davvero utile: ti guida attraverso il processo e sembra pericolosa.

alt text http://www.red-gate.com/products/ants_memory_profiler/images/object_retention_graph.gif

0

Ecco paio di trucchi che utilizzano il ANTS Memory Profiler per aiutare a trovare gli oggetti undisposed e fissare le perdite.

  1. il profilo memoria ANTS permette un filtro da impostare che mostrano solo oggetti che contengono un metodo Dispose(). Attiva, e sarai dato un elenco di oggetti live che non sono stati eliminati.

  2. Mentre trovare gli oggetti non esposti è utile, ancora più utile è sapere perché questi oggetti non vengono smaltiti. La ricerca di dove vengono creati questi oggetti non disposti è molto utile per trovare il motivo per la perdita. Se sei in grado di modificare il codice dell'oggetto che perde, un trucco utile consiste nell'introdurre un campo per contenere uno stacktrace e popolare questo campo al momento della costruzione dell'oggetto. Quindi, poiché il profiler della memoria ANTS consente di ispezionare i campi degli oggetti, è possibile leggere semplicemente lo stacktrace come era nel momento in cui gli oggetti che perdevano erano stati creati. Questo ti darà una chiara idea di chi dovrebbe essere il proprietario di oggetti che perdono, e come dovrebbero andare a chiamare Dispose sugli oggetti di cui sono responsabili.