2013-11-20 8 views
6

Da GC.KeepAlive() on MSDN:Perché chiamare GC.KeepAlive alla fine e non all'inizio?

Codice questo metodo, alla fine, non l'inizio, della gamma di istruzioni dove obj devono essere disponibili.

Perché ha un comportamento non intuitivo?

+3

'riferimento all'oggetto specificato, il che lo rende ineleggibile per la raccolta dei rifiuti dall'inizio della routine corrente al punto in cui questo metodo è chiamato "Questa definizione è abbastanza chiara. –

+0

@AlexFarber Sì, la definizione è abbastanza chiara. Ma quello che mi aspetto è sapere perché è stato progettato in quel modo. – Doug

risposta

17

Perché altrimenti tecnicamente il JIT e la CLI potrebbero determinare che il valore non viene utilizzato dopo quel punto e considerare l'oggetto valido per la raccolta. Diamine, il compilatore potrebbe decidere di rimuovere completamente la variabile e solo "pop" dalla pila dopo l'ultimo utilizzo.

Si noti che GC.KeepAlivein realtà non fa nulla. È un metodo opaco, non operativo. Il punto è che se si chiama un metodo opaco con un oggetto come parametro, quell'oggetto deve ancora essere intorno a, cioè raggiungibile, vale a dire non raccoglibile.

Ecco come KeepAlive implementata (con alcuni attributi non interessanti rimossi):

[MethodImpl(MethodImplOptions.NoInlining)] 
public static void KeepAlive(object obj) 
{ 
} 
+0

Ok, vedo come GC.KeepAlive è solo un riferimento fasullo. Ma non sono chiaro sul perché il compilatore non può decrementare il ref-count DOPO l'ultimo metodo chiamato sull'oggetto restituisce effettivamente. Vedi: http://msdn.microsoft.com/en-us/library/system.gc.keepalive(v=vs.80).aspx – jeff7091

+0

@ jeff7091 ti rendi conto che non c'è alcun riferimento alla CLI, giusto? Inoltre, il punto di 'GC.KeepAlive' non riguarda i metodi - un uso comune sono cose che hanno finalizzatori - ad esempio un timer o un tracciante che si desidera mantenere in esecuzione per la durata di qualcosa, che non si vuole essere raccolti –

Problemi correlati