2012-07-23 23 views
8

Estoy haciendo una presentación introductoria sobre .Net CLR GC y tengo todas las piezas, pero quería un ejemplo específico de cómo tratar de forzar la recolección podría ser peligroso o dañino. Sé que puedes forzar las cosas en las generaciones más altas prematuramente, pero (por lo que pude ver) eso realmente solo desaceleraría las cosas.¿Un ejemplo de GC forzado ha ido mal?

Estoy tratando de pensar en una situación en la que forzar GC podría ser realmente perjudicial y sigo surgiendo con soluciones meramente menos eficientes.

+2

La pérdida de tiempo es el único inconveniente. – Dialecticus

+0

Al "forzar la recopilación" supongo que quieres decir llamando a GC.Collect(). ¿Por qué crees que eso sería peligroso? ¿Hay alguna documentación que eché de menos que así lo diga? (Me doy cuenta de que la probabilidad es alta, ya que no puedo mantener el ritmo en estos días.) – David

+0

¿Es posible que el temporizador sea apretado con requisitos en tiempo real? – leppie

Respuesta

4

Aquí hay una demostración interesante. Tenga en cuenta que debe ejecutar esta demostración compilada en modo de lanzamiento o puede no funcionar como se anuncia.

Versión 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(); 
} 

Versión 1 imprimirá felizmente la fecha y la hora a la caja de texto de una vez por segundo.

Versión 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 
} 

ahora en la versión 2, la fecha y la hora solamente será impreso una vez porque, después de la declaración, no hay más referencias al objeto de temporizador, por lo que el objeto de temporizador se pone recogido.

Es un ejemplo bastante artificial pero puede ser una buena demostración.

Debo acreditar a Jeffery Richter por este - está en su excelente libro CLR via C#.

+0

Creo que este comportamiento sería más inesperado si acaba de llamar 'new Timer (... 'y no guarda el valor devuelto. –

+2

Pero en este caso, 'GC.Collect()' no es malo, en realidad es bueno, porque lo ayudó a descubrir un error en la aplicación. Sin 'GC.Collect()', misteriosamente dejaría de funcionar en el futuro. – svick

+0

@svick - buen punto. tal vez es solo una mejor lección sobre el alcance. en cualquier caso, es interesante y hace pensar en el GC. – James

1

¿Qué tal lo siguiente, mala idea? "¡Forzamos un GC después de cada solicitud de HTTP en ASP.NET para limpiar el estado de solicitud que seguramente quedará huérfano!"

No es una buena idea porque la solicitud HTTP concurrente interferiría entre sí. Esto introduciría muchos picos de latencia y destruiría el rendimiento. Todo eso comenzando desde una inocente "optimización".

Eso es lo peor que se me ocurre.

Cuestiones relacionadas