2013-11-05 5 views
6

Supponiamo di avere un Collection<B> e che stai per rimuovere un articolo. Istanza di B si fa riferimento da un'istanza di A, e riferimenti un'istanza di C, come mostrato nella prima immagine:.NET La rimozione di una classe genitore trasforma i bambini in "garbage"?

Figure A http://i43.tinypic.com/240wuqh.jpg

Ora, dal momento che c'è stata una punta di riferimento a B, non c'è alcun dubbio circa la oggetto "cancellato" o garbage collection. Viene semplicemente rimosso dalla raccolta, in questo modo, giusto?

Figure B http://i41.tinypic.com/4uxnp3.png

Ora, diamo uno Collection<A> con la stessa gerarchia referenziale, come prima, e cerchiamo di rimuovere un'istanza di A.

Figure C http://i44.tinypic.com/1zd93dt.png

Se non c'è nessun altro riferimento al A, non solo viene rimosso dalla raccolta, è contrassegnato come spazzatura. Ho ragione? E che dire di B e C? Diventano anche rifiuti, a condizione che non ci siano altri riferimenti tranne B che fanno riferimento a un'istanza di C?

Questa è una semplificazione di ciò che sto affrontando. Desidero rimuovere un'istanza A da una raccolta e voglio assicurarmi che B e C seguano questa procedura. Nel punto in cui A non è più nella mia raccolta, tutti i "bambini" che sono ancora vivi sono una perdita di memoria per me.

Quando guardo queste foto che ho fatto, sembra una domanda troppo stupida. Ma la mia situazione è un po 'meno banale. Sembra qualcosa di simile:

figure 4 http://i41.tinypic.com/2ymhlq0.png

  • Nella foto, livello del Modello è di colore giallo, strato ViewModel è verde
  • La classe 'A ViewModel' fa riferimento al relativo A Model
  • Il A Model ha una collezione delle istanze B Model (B è il tipo di figlio di A, sia nei livelli Model che ViewModel)
  • ogni B Model "sa che ts genitore '- fa riferimento a suo padre 'Un modello' esempio
  • di nuovo a livello di VM, la 'A ViewModel' ospita una collezione di 'B ViemModel' articoli
  • come ogni buon ViewModel, 'B Modello B ViewModel' Riferimenti' '

Ho una raccolta di quelle istanze A ViewModel. Quando ne cancello uno, ho bisogno di tutto il resto per farlo. A condizione che non ci siano altri "riferimenti esterni" a nessuna delle istanze coinvolte (in pratica, nessun'altra freccia che punta dall'esterno dell'immagine), l'istanza "A ViewModel" rimossa porterà tutti i bambini con essa? Se è così, ci sono dei "trucchi" che potrebbero rendere questa semplificazione fuorviante? E se ho torto completamente, perché? :)

Grazie per aver letto fino a qui!

+1

Prestare attenzione alle perdite di memoria. Ad esempio, un metodo 'Dispose' scritto male sulla classe' B' (lanciare, ad esempio, una 'NullReferenceException') potrebbe impedire che un'istanza' B' (e tutti i suoi oggetti di riferimento, inclusa l'istanza 'C') siano spazzatura raccolto. Ci sono alcuni scenari interessanti su [questo] (http://stackoverflow.com/questions/20386/memory-leaks-in-net) risposta. – rsenna

+1

@rsenna Descrive una perdita in * risorse non gestite *, non una perdita nelle risorse * managed *. 'A' che ha un finalizzatore che lancia non gli impedisce di essere sottoposto a GC, né impedisce che B o C vengano sottoposti a GCed. Se il finalizzatore blocca per sempre * allora * potrebbe farlo. – Servy

risposta

10

Purché non c'è altro "riferimento al di fuori" a qualsiasi delle istanze coinvolte (in pratica, nessun altro freccia che punta proveniente dall'esterno del quadro), sarà il rimossi esempio 'A ViewModel' prendere tutti i bambini con esso ?

Sì, purché non ci siano riferimenti dal codice al figlio, esso sarà idoneo per la garbage collection e alla fine verrà raccolto.

Se non c'è altro riferimento ad A, non solo viene rimosso dalla raccolta, viene contrassegnato come garbage. Ho ragione?

Questo non è in realtà come funziona. Il GC non "traccia la spazzatura" - invece, controlla tutti i riferimenti agli oggetti dal codice attualmente in esecuzione e esce per trovare riferimenti che sono attualmente "vivi". Tutto ciò che rimane a quel punto non è vivo, e quindi diventa idoneo per la raccolta. Se l'unico modo per raggiungere "B" o "C", nel tuo grafico, è attraverso quell'istanza di "A" e rimuovi "A" dalla raccolta, tutti quelli diventeranno idonei per GC e saranno trovati nel prossima raccolta GC appropriata.

+0

Grazie per la risposta chiara! –

Problemi correlati