2009-06-10 2 views
7

Ho un'app WPF che, tra le altre cose, mostra molte immagini, grandi e piccole. Il mio problema è che l'app utilizza molta memoria e non riesco a capire da dove provenga.dov'è finita la mia memoria? grandi numeri di byte privati ​​

Lo scenario, quando sottolineando l'applicazione certa ottengo questo grafico in Perfmon:

http://www.imagechicken.com/uploads/1244548604007097000.jpg

La grande linea nera è Processo \ Byte privati ​​e le altre linee sono i contatori CLR MEM (quello rosa è totale byte vincolati)

in numeri nel grafico sono:
byte privati ​​~ 350 Mb
byte vincolati ~ 100 Mb

Ho scavato in giro un sacco con WinDbg e altri strumenti, e tutti riportano che lo stack gestito si comporta (stack! Rapporti eeheap totale gestito di circa 100 Mb)

ho rovistando con applicazioni come LeakDiag, LDGrapher ma non ha trovato nulla.

Quindi, finalmente alla mia domanda, come posso procedere per scoprire dove sta andando la mia memoria?

Anche solo l'avvio dell'applicazione utilizza 100 MB in byte impegnati ma 190 MB in byte privati.

Riferimenti:

Ho letto molto su questo, tra gli altri, sui grandi siti:

Tess Ferrandez: http://blogs.msdn.com/tess/archive/2009/02/27/net-memory-leak-reader-email-are-you-really-leaking-net-memory.aspx

Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx

MSDN mag: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx

+0

Grazie per le risposte finora. Quindi, per chiarire,! Eeheap,! Dumpheap, gcroot ecc. Tutti riportano le cose che compongono il 100Mb - quello che sto cercando di eliminare è l'altra memoria - i 250 Mb aggiuntivi. Aggiornamento – andyhammar

+0

- con VADUMP: Rapporti "Grande set di lavoro totale" di 236 Mb, "Altri dati" come 196 Mb. Nel frattempo! Eeheap riporta "GC heap size" a 107336836. Qual è questa differenza? – andyhammar

+0

'Altri dati' include l'heap GC insieme ad altri dati :) Non sono sicuro di cos'altro c'è, ma è sicuro assumere che siano i dati di runtime richiesti dal CLR. –

risposta

1

Scarica MemProfiler da Scitech. Ha una versione di prova di 14 giorni.

Il problema segnalato è spesso dovuto a viste/risorse che non possono essere eliminate a causa di una radice nell'heap. Una causa comune non sono i gestori di eventi indesiderati.

+0

Grazie Mitch. Ho giocato un po 'con MemProfiler e ho trovato un sacco di byte [] da "MergedDictionaries" (una cosa WPF). Sto cercando di aggiustarlo adesso. Questo non è tutto ma qualcosa, grazie! – andyhammar

3

Solo perché l'applicazione utilizza molta memoria non significa necessariamente una perdita di memoria. Dalle informazioni nella tua domanda è difficile affermare ciò che potrebbe essere sbagliato.

Quando si hanno problemi di perdite di memoria gestite con WinDbg faccio la seguente:

  • avere una panoramica di utilizzo heap con !eeheap (questo riporta l'utilizzo di heap e non lo stack come si parla - ogni pila ha una dimensione predefinita di 1 MB, quindi a meno che non si è cambiato questo non c'è modo è possibile utilizzare 100 MB nello stack)

  • fare un !dumpheap -stat per scoprire che cosa è sul mucchio. Le probabilità sono che se si ha una perdita di memoria, il/i tipo/i colpevole/i sarà tra i migliori consumatori.Per avere un'idea di come si sviluppa l'utilizzo dell'heap, è possibile riprendere l'applicazione, interromperla un po 'più tardi e quindi ripetere il comando !dumpheap -stat.

  • Se trovate qualunque tipo con più istanze di quanto si possa Tranne, elencare quelli che utilizzano !dumpheap -mt <MT of type>. Questo elencherà tutte le istanze del particolare tipo. Seleziona istanze casuali e controlla le radici usando il comando !gcroot. Questo ti dirà cosa mantiene vivi i casi in questione. Se non ci sono root queste istanze verranno raccolte ad un certo punto.

UPDATE per rispondere ai vostri commenti:

Il mucchio gestito è solo una parte del footprint di memoria di un'applicazione gestita. Ricorda che un'applicazione .NET è davvero un'applicazione all'interno di un'altra applicazione, il processo host, che carica il CLR, che a sua volta carica la tua applicazione. Quindi, prima che l'applicazione inizi a utilizzare qualsiasi memoria, il CLR ha già preso una giusta quota. Oltre a questo, le applicazioni .NET archiviano sia il codice MSIL che il codice compilato JIT come parte del footprint. Il CLR occupa spazio anche per varie attività di contabilità (ad esempio, il CLR crea due AddDomain aggiuntivi per uso interno).

I numeri che mi danno non mi sembrano esagerati, ma visto che non conosco la tua domanda, è difficile dire se sono eccessivi.

100 MB sull'heap gestito potrebbero essere a posto, a seconda di cosa sta facendo l'applicazione. Hai controllato l'heap? E se sì cosa hai trovato?

+0

Grazie Brian! Con un ammontare di 139 596 684, i miei più grandi mem-user sono: 1) System.Byte [] (14949 articoli, mem: 32 217 996), 2) System.String (475 010 articoli, mem: 31 016 248) e 3) System.Windows.Markup.BamlDefAttributeKeyStringRecord (elementi: 230 845 mem: 11 080 560). Il byte [] s deriva dalla lettura di immagini dal disco e dalla creazione di BitmapSources. Le stringhe che non conosco, probabilmente una cosa WPF ... – andyhammar

+0

Un altro campione: totale impegnato: 178 Mb, byte privati: 538 Mb. Scavando ulteriormente ... – andyhammar

1

Si potrebbe provare a leggere this article in the latest MSDN magazine. Va in dettaglio su come usare VADump per capire di più su dove è dedicata la memoria di un processo.

È possibile scaricare VADUMP qui: http://go.microsoft.com/fwlink/?LinkId=149683

per abbattere l'heap gestito, si potrebbe provare un profiler di memoria. Personalmente mi piace JetBrains dotTrace.

+0

Grazie Drew, vadump non ha funzionato per me ieri ma l'ho provato ora - riporta i numeri che non corrispondono a eeheap. Ho postato un commento alla mia domanda. – andyhammar

4

Ho avuto un problema simile in un'applicazione WPF e used UMDH to track in cui veniva allocata la memoria nativa. (Si noti che di solito è utile per set _NT_SYMBOL_PATH ottenere buone tracce di stack dai componenti del sistema operativo

I registri hanno mostrato che quasi tutta la memoria era allocata nel driver video. Ho trovato che il driver era più di un anno . fuori moda, ho installato l'ultima versione dal sito web del produttore e che risolto il problema

0

una risposta: si va a troppi ResourceDictionaries unite (una cosa WPF)

Dettagli: per essere in grado di vedere il design in fase di progettazione in Blend e VS, abbiamo usato per unire il nostro dizionario risorse tema sulla maggior parte delle pagine xaml. Ciò ha causato una copia di tutte le risorse da caricato per ogni controllo, maggiori informazioni possono essere lette qui: [WPF Discepoli] [1]

Quindi l'unico posto in cui li unisco ora è App.xaml.cs:

<Application.Resources> 
    <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary 
     Source="pack://application:,,,/Company.Themes;Component/AppTheme.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Risultati: (in esecuzione l'applicazione tramite alcune pagine con un test automatico GUI)

Prima:

  • dopo il carico app: 63 Mb
  • dopo l'uso di app : 177 Mb

Dopo:

  • Dopo carico app: 53 Mb
  • Dopo l'utilizzo di app: 97 Mb

vi posterò più risposte come li trovo! (ho pensato che sarebbe stato più facile per i lettori di vedere il mio constatazione risposte separati invece di replys a commenti - buona?)

[1]: ref: http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1