Hay una manera mucho más fácil si todo lo que quiere hacer es descubrir cuándo se está ejecutando GC, no le dirá exactamente cuándo comienza, ni cuándo terminará, pero si puede ver el resultado de esto método que describiré aquí cuando notes las pausas en tus servidores, deberías ser capaz de averiguar si GC es tu problema.
Básicamente, lo que debes hacer es crear una clase con un finalizador, construir un objeto de esa clase y simplemente soltar la referencia (es decir, no almacenarla). El objeto se dejará hasta que GC lo golpee, donde se finalizará.
El truco ahora está en el finalizador que registra (de la manera que quiera usar) que el finalizador haya ejecutado, y a menos que el dominio de aplicación esté en proceso de cierre, simplemente construye un nuevo objeto que cae rápidamente la referencia a, listo para el próximo CG.
Esto funciona sorprendentemente bien y no necesita mucho trabajo de su parte.
Aquí está la clase que utilizo:
namespace PresentationMode
{
/// <summary>
/// This class is used to get a running log of the number of garbage collections that occur,
/// when running with logging.
/// </summary>
public sealed class GCLog
{
#region Construction & Destruction
/// <summary>
/// Releases unmanaged resources and performs other cleanup operations before the
/// <see cref="GCLog"/> is reclaimed by garbage collection.
/// </summary>
~GCLog()
{
SiAuto.Main.LogMessage("GARBAGE COLLECTED");
if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted)
new GCLog();
}
#endregion
#region Public Static Methods
/// <summary>
/// Registers this instance.
/// </summary>
public static void Register()
{
#if DEBUG
if (SiAuto.Si.Enabled)
new GCLog();
#endif
}
#endregion
}
}
Todo lo que tiene que hacer es llamar al método .Register()
. Tenga en cuenta que uso SmartInspect como herramienta de registro, por lo que desea reemplazar las llamadas relacionadas con SiAuto
con otra cosa.
En otro proyecto, también usando SmartInspect, que tiene la noción de 'relojes', donde puede enviar valores numéricos y graficarlos en la herramienta de registro, envié los valores 0, 1 y luego 0 en rápida sucesión , ya que esto me daría un gráfico que se mantuvo en 0 en todo momento, pero produjo un pico agudo cada vez que había un GC funcionando. Unir esto con un hilo de fondo que monitorea el uso de la CPU y la memoria utilizada me dio datos muy buenos para trabajar.
Gracias por sus comentarios, eso fue rápido :-) Ya he estado buscando la respuesta por un tiempo, por lo que ya sé sobre estas sugerencias (primeros 3 comentarios). Quiero mostrar en una línea de tiempo cuando el GC está funcionando y cuando no lo está. Entonces, saber cuándo se hace, o cuánto tiempo ha estado usando desde la última colección, no servirá. Estoy bastante sorprendido de que aún no haya podido encontrar la solución, pero si no existe nada, intentaré escribir mi propia herramienta hax0r para hacerlo. gracias de nuevo! – Rabbit