2010-09-09 9 views
13

Tengo una ralentización extraña en mi sitio web ASP.NET que parece que no puedo rastrear. Sospecho que GC podría estar dando patadas y deteniendo mis hilos. Para estar seguro, sería bueno iniciar sesión cada vez que se produzca GC.¿Hay un evento para cuando se produce la recolección de basura en .NET?

Podría hacer un objeto ficticio y hacer el registro en su finalizador, pero eso sería una solución de una sola vez, mientras que en mi caso hay varias pausas inexplicables.

¿Alguna idea?

Agregado: El entorno es VS2008/.NET 3.5 SP1. Y no, el Garbage Collection Notifications no funcionará porque son un método de sondeo, y no funcionan para un GC concurrente.

+0

Eso depende de la versión del marco que esté utilizando. –

+0

Pregunta interesante aunque – serg10

Respuesta

2

Perhpas this artículo (Notificaciones de recogida de basura) ayudará.

puede ser notificado de que una recolección completa se acerca

+0

No está garantizado que suceda, y es más como un sondeo, mientras que necesito un evento. –

1

¿Supervisa perf-mon? Puede ver la CPU, en general y por proceso, la memoria .NET, incluido el tamaño de cada una de las generaciones y los recuentos de los tipos de GC. También puede dejar que perf-mon se ejecute y se registre durante períodos prolongados para observar las tendencias. ¡Encuentro que esto es mucho más útil que lo discreto que está sucediendo en este momento! eventos.

+1

Específicamente, probablemente desee el objeto .NET CLR Memory Performance. Desde allí, puede obtener los contadores de GC para un grupo de aplicaciones específico. –

1

La respuesta simple es "No, no hay 'eventos' GC 'solo la función GCNotificación". Sin embargo, usted crea una clase contenedora que escuchará GCNotification y esa envoltura puede desencadenar eventos, pero no hay una solución de evento simple como la que está buscando.

La razón de esto es que un evento puede o no procesarse antes de que se complete el GC. Entonces, lo que tienen que hacer es engendrar un hilo secundario, dormir en WaitForFullGCApproach o polo si no está buscando un GC completo, y hacer lo que sea necesario antes de que ocurra el GC.

0

Es posible que desee leer este artículo sobre ASP.NET Performance Monitoring, and When to Alert Administrators

Incluye una sección sobre los GCcounters a la vista y lo que los valores medios. Por ejemplo

% Tiempo en GC. El porcentaje de tiempo dedicado a realizar la última recolección de basura . Un valor promedio del 5% o menos se consideraría saludable, pero picos más grandes que esto no son poco comunes. Tenga en cuenta que todos los hilos son suspendidos durante una recolección de basura.

También puede ser que desee echar un vistazo al blog If broken it is, fix it you should Tiene una serie de estudios de casos que van paso a paso sobre cómo identificar un problema específico. Por ejemplo ASP.NET Case Study: High CPU in GC - Large objects and high allocation rates

8

Aquí hay un truco simple. Puede que no sea 100% exacto, pero probablemente sea lo suficientemente bueno.

Si puede vivir avisado de la finalización, entonces hay un método simple que puede usar.

Crea un objeto y no lo sigas haciendo referencia. Cuando el objeto está finalizado, levantas tu evento y luego construyes otro objeto.Tampoco guarda una referencia a este objeto, pero seguirá vivo hasta la próxima vez que se realice una recopilación completa.

Aquí es un objeto:

public class GCNotifier 
{ 
    public static event EventHandler GarbageCollected; 

    ~GCNotifier() 
    { 
     if (Environment.HasShutdownStarted) 
      return; 
     if (AppDomain.CurrentDomain.IsFinalizingForUnload()) 
      return; 
     new GCNotifier(); 
     if (GarbageCollected != null) 
      GarbageCollected(null, EventArgs.Empty); 
    } 

    public void Start() 
    { 
     new GCNotifier(); 
    } 
} 

Si lo desea, puede añadir soporte para detenerlo por tener un campo booleano estático que evita que se vuelve a funcionar tras la próxima finalización.

Espero que esto sea de alguna ayuda.

Cuestiones relacionadas