2009-07-08 9 views
25

Capisco e apprezzo l'utilità della classe System.WeakReference nel .NET framework, ma sono curioso di vedere i dettagli di implementazione.WeakReference in .NET

Come viene implementato WeakReference in .NET? MSDN discute l'utilizzo di WeakReference in dettaglio, ma ha pochi dettagli che ho visto su come funziona sotto il cofano.

Come fa il CLR traccia il riferimento e sapere a null la maniglia interna quando il bersaglio viene raccolto, senza impedire il GC? Richiede una gestione speciale nel CLR stesso?

La mia preoccupazione principale sarebbe se ci sono inerenti le prestazioni nell'uso WeakReferences (soprattutto se si utilizza molti di loro) che differiscono da quelli di utilizzare riferimenti a oggetti standard.

+5

allora ho fatto un bel po 'di ricerca, e bloggato sui miei risultati in dettaglio: http://reedcopsey.com/?p=50 –

risposta

19

La classe WeakReference consegna il riferimento dell'oggetto al GC e recupera una maniglia. Ogni volta che ottieni il riferimento o verifica se il riferimento è attivo, l'handle viene utilizzato per chiedere al GC il riferimento.

Ciò significa che il GC mantiene un elenco di tutti i riferimenti deboli, quali deve aggiornare quando gli oggetti sono raccolti. Significa anche che c'è un sovraccarico ogni volta che usi un riferimento debole.

Così, ogni riferimento debole significa un po 'di lavoro per il garbage collector, ma d'altra parte così fa ogni riferimento regolare troppo, anche se è meno. Ovviamente dovresti essere un po 'cauto nell'usare molti riferimenti deboli, ma se hai bisogno che la gestione della memoria funzioni bene con gli oggetti, ciò dovrebbe superare il piccolo sovraccarico che causa.

+1

Imposterò questa risposta come una buona descrizione di base del processo. Grazie Guffa. –

13

Hai menzionato MSDN; hai già visto questo articolo?

http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

controllare anche il capitolo 19 in "Programmazione Applied Microsoft .NET Framework" dello stesso autore (Jeffrey Richter). Il capitolo è sulla raccolta dei rifiuti e ha una sezione sugli interni di WeakReference.

In generale, se si sta accedendo un sacco di Targets all'interno WeakReferences, poi c'è una performance colpire semplicemente perché il weakref fa un lavoro (per lo più per la sicurezza filo) prima di ritornare il bersaglio. Questo ovviamente non è economico come usare direttamente il riferimento all'oggetto. D'altra parte, si ottengono prestazioni quando si memorizzano riferimenti a oggetti di grandi dimensioni, poiché il garbage collector ha più opzioni quando si verificano considerazioni sulla memoria.

Non ho mai provato a quantificare questo scambio, o sapere di qualsiasi riferimento qui. Ovviamente varia un po 'a seconda dell'applicazione.

+2

+1, e grazie per il materiale di riferimento. Solo FYI, ho fatto più ricerche, e ci sono sorprendentemente poco spese generali per la sicurezza dei thread in WeakReference - principalmente, è questione di dover portare GCHandle a restituire l'oggetto, che si comporta come il dereferenziazione due volte, più un paio di controlli nulli. –

+0

Pensavo di essermi ricordato di averlo visto un paio di anni fa, ma avrei dovuto confermarlo prima di metterlo nella risposta. Grazie per averlo notato, Reed. – ars

+0

+1 per materiale di riferimento a portata di mano. –