Domanda

Ho un app WindowsForms che sembra una perdita di memoria, così ho usato di Redgate ANTS Memory Profiler per guardare gli oggetti ho il sospetto e scoprire che essi sono tenuti solo da oggetti già sul Finalizer coda . Grande, esattamente quello che è un Queue Finalizer? Mi può indicare la migliore definizione? Puoi condividere qualche consiglio aneddotica?

Inoltre, tutti gli oggetti GC radice sulla coda Finalizer sono casi di System.Windows.Forms.Control + ThreadMethodEntry oggetti con nome "chiamante". Vedo che è coinvolto in interazione utente multi-thread, ma io non ne so molto di là di questo. Perdonate la mia apparente pigrizia e l'ignoranza ha ammesso, ma queste risorse sono tutti sepolti all'interno di componente di un fornitore. Sto parlando al venditore su questi problemi, ma ho bisogno di qualche direzione per farmi fino a velocità sulla conversazione. Mi può indicare la definizione più utile di ThreadMethodEntry troppo? Qualche consiglio aneddotica?

Inoltre, dovrei anche essere preoccupato per questi oggetti sulla coda finalizzatore?

Aggiornamento: Questo articolo Red gate era disponibile.

È stato utile?

Soluzione

La coda finalizzatore contiene tutti gli oggetti che hanno un metodo finalizzatore definito. Ricordiamo che un finalizzatore è un mezzo per raccogliere le risorse non gestite come maniglie. Quando il garbage collector raccoglie spazzatura, si muove qualsiasi oggetto con un finalizzatore nella coda finalizzatore. Ad un certo punto later-- a seconda della pressione di memoria, euristica GC, e la fase del moon-- quando il garbage collector decide di raccogliere questi oggetti, si cammina lungo la coda e gestisce i finalizzatori.

Dopo aver lavorato con le perdite di memoria, in passato, di vedere un mucchio di oggetti del fornitore nella coda finalizzatore potrebbe essere il codice sciatta, ma non indica una perdita di memoria. In genere, buon codice esporrà un metodo Dispose che raccoglierà sia le risorse gestiti e non gestiti, e così facendo, allontanarsi dalla coda finalizzatore via GC.SuppressFinalize(). Quindi, se gli oggetti del venditore fanno implementare un metodo Dispose, e il codice non lo chiamano, che potrebbe portare a un gruppo di oggetti in coda finalizzatore.

Hai provato a creare un'istantanea di formiche tra due punti nel tempo e confrontando gli oggetti creati tra di loro? Che possono aiutare a identificare gli oggetti gestiti essere trapelato.

Inoltre, se si vuole vedere se la memoria va via quando i finalizzatori vengono eseguiti, provate questo solo per testare con:

System.GC.Collect();
System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers
System.GC.Collect();

Non consiglio di eseguire il codice normalmente. Si potrebbe desiderare di farlo funzionare se hai appena fatto un sacco di lavoro e creato un sacco di spazzatura. Per esempio, nella nostra applicazione, una delle nostre funzioni in grado di creare circa 350 MB di spazzatura che va a rifiuti dopo la chiusura di una finestra MDI. Dal momento che questo è noto a lasciare un sacco di spazzatura, abbiamo forzare manualmente la raccolta dei rifiuti.

Si noti inoltre che v'è una cache di proprietà di basso livello nel codice Windows.Forms di base che si terrà fino all'ultimo ha aperto finestra di dialogo modale. Questa potrebbe essere una fonte di una perdita di memoria. Un modo sicuro per sbarazzarsi di questo riferimento è quello di forzare un'altra finestra di dialogo semplice di apparire, quindi eseguire il codice GC sopra.

Altri suggerimenti

La coda finalizzatore è una coda in cui le istanze di oggetti che non vengono più utilizzati sono in attesa di essere messo a punto dal GC. Tutti gli oggetti in questa coda saranno finalizzati e le tue perdite di memoria non probabilmente provengono da uno di questi quelli direttamente. Ma, uno di questi oggetti potrebbero non rilasciare tutte le sue risorse non gestite.

La classe ThreadMethodEntry è un implementazioni di IAsyncResult e istanze di questa classe sono tipicamente creati quando si invoca operazioni asincrone, come l'utilizzo di Invoke per aggiornare l'interfaccia utente o utilizzando Begin * / Fine * metodi.

Ecco un buon post sul blog che descrive un problema simile. A un livello più tecnico, si potrebbe cercare di utilizzare Sos.dll (che il post sul blog descrive) e Sosex.dll per aiutare a capire il motivo per cui questi oggetti ThreadMethodEntry sono appesi intorno in memoria. Ci sono comandi in queste estensioni WinDbg che possono rintracciare ciò che gli altri oggetti fanno riferimento un oggetto specifico in memoria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top