Vedi anche queste risorse correlati:Un compilatore C# conforme può ottimizzare una variabile locale (ma non utilizzata) se è l'unico riferimento forte a un oggetto?
- Does the .NET garbage collector perform predictive analysis of code? (su Stack Overflow)
- WP7: When does GC Consider a Local Variable as Garbage (articolo del blog su MSDN)
In altre parole:
Può un oggetto a cui fa riferimento una variabile locale essere recuperato prima della variabile esula dall'ambito (es. perché la variabile è assegnato, ma poi non riutilizzato), o è che oggetto garantita ammissibili per garbage collection finché la variabile passa nell'ambito?
Mi spiego:
void Case_1()
{
var weakRef = new WeakReference(new object());
GC.Collect(); // <-- doesn't have to be an explicit call; just assume that
// garbage collection would occur at this point.
if (weakRef.IsAlive) ...
}
In questo esempio di codice, io ovviamente devo pianificare per la possibilità che la new'ed object
venga recuperato dalla garbage collector; quindi la dichiarazione if
.
(Si noti che sto usando weakRef
per il solo scopo di verificare se il new'ed object
è ancora in giro.)
void Case_2()
{
var unusedLocalVar = new object();
var weakRef = new WeakReference(unusedLocalVar);
GC.Collect(); // <-- doesn't have to be an explicit call; just assume that
// garbage collection would occur at this point.
Debug.Assert(weakRef.IsAlive);
}
Il cambiamento principale in questo esempio di codice da quella precedente è che il new'ed object
è fortemente referenziato da una variabile locale (unusedLocalVar
). Tuttavia, questa variabile non viene mai più utilizzata dopo la creazione del riferimento debole (weakRef
).
Domanda: è un conforme compilatore C# permesso di ottimizzare le prime due righe di Case_2
in quelle di Case_1
se vede che unusedLocalVar
viene utilizzato solo in un posto, vale a dire come un argomento al costruttore WeakReference
? cioè c'è qualche possibilità che l'asserzione in Case_2
possa mai fallire?
Si noti inoltre che, nelle build di debug, la variabile viene mantenuta in modo esplicito alla fine dell'ambito per consentire al debugger di essere visualizzato - è solo nelle build di rilascio che verrà visualizzato questo comportamento. –
@Andy - punto interessante. Non che sia importante, ma immagino che questo comportamento sia governato dal JITter? –
E per completezza, ecco perché l'impostazione di 'unusedLocalVar = null' al _end_ del metodo è solitamente una de-ottimizzazione. –