2012-07-23 18 views
8

Sto facendo una presentazione di introduzione su .Net CLR GC e ho tutti i vari pezzi, ma volevo un esempio specifico di come provare a forzare la raccolta potrebbe essere pericoloso o dannoso. So che puoi forzare le cose nelle generazioni più anziane prematuramente, ma (da quello che potrei dire) che farebbe solo rallentare le cose.Un esempio di GC forzato andato a male?

Sto cercando di pensare a una situazione in cui forzare GC potrebbe essere davvero dannoso e continuo a venire con soluzioni solo meno efficienti.

+2

La perdita di tempo è l'unico inconveniente. – Dialecticus

+0

Con "forzare la raccolta" presumo intendi chiamando GC.Collect(). Perché pensi che sarebbe pericoloso? C'è qualche documentazione che ho perso che dice così? (Capisco che la probabilità è alta, dato che non riesco a stare al passo in questi giorni.) – David

+0

Timer stretto con requisiti in tempo reale forse? – leppie

risposta

4

Ecco una dimostrazione interessante. Nota che dovresti eseguire questa demo compilata in modalità di rilascio o potrebbe non funzionare come pubblicizzato.

Versione 1:

private void Button_Click(object sender, EventArgs e) 
{ 
    Timer timer = new Timer(Print, null, 0, 1000); 
} 

private void Print(Object o) 
{ 
    if (textBox1.InvokeRequired) 
    { 
     Action<object> action = Print; 
     textBox1.Invoke(action, o); 
     return; 
    } 

    textBox1.Text = DateTime.Now.ToString(); 
} 

Versione 1 sarà lieto di stampare la data e l'ora per la casella di testo una volta al secondo.

Versione 2:

private void Button_Click(object sender, EventArgs e) 
{ 
    Timer timer = new Timer(Print, null, 0, 1000); 
} 

private void Print(Object o) 
{ 
    if (textBox1.InvokeRequired) 
    { 
     Action<object> action = Print; 
     textBox1.Invoke(action, o); 
     return; 
    } 

    textBox1.Text = DateTime.Now.ToString(); 

    GC.Collect(); // force a garbage collection 
} 

ora in versione 2, la data e l'ora verrà stampato solo una volta, perché, dopo la dichiarazione, non ci sono più riferimenti all'oggetto timer, e così l'oggetto del timer ottiene raccolto.

Questo è un esempio abbastanza forzato ma può costituire una buona dimostrazione.

Devo accreditare Jeffery Richter per questo - è nel suo eccellente libro CLR via C#.

+0

Credo che questo comportamento sarebbe più inaspettato se si chiamasse 'new Timer (...' e non si salvi il valore restituito. –

+2

Ma in questo caso, 'GC.Collect()' non è male, in realtà è buono, perché ti ha aiutato a scoprire un bug nell'applicazione. Senza 'GC.Collect()', misteriosamente smetterebbe di funzionare un po 'di tempo in futuro. – svick

+0

@svick - buon punto. forse è solo una lezione migliore sulla scoping. in ogni caso, è interessante e fa pensare al GC. – James

1

E la seguente, cattiva idea? "Forza un GC dopo ogni richiesta HTTP in ASP.NET per pulire lo stato della richiesta che sarà sicuramente orfano!"

Questa è una cattiva idea perché la richiesta HTTP simultanea interferirebbe l'una con l'altra. Ciò introdurrebbe un sacco di picchi di latenza e distruggerebbe le prestazioni. Tutto ciò a partire da una "ottimizzazione" innocente.

Questo è il peggiore che riesco a pensare.