Timing how long garbage collection is taking in C# I'm concerned about how much time my application could be spending during garbage collection so I'm trying to figure out how to add some code to instrument this.

Based on some examples:


https://msdn.microsoft.com/en-us/library/cc713687(v=vs.110).aspx
http://www.codeproject.com/Articles/101136/Garbage-Collection-Notifications-in-NET


I've come up with the code below. I'm see GC taking around 200 ms locally.
Does anyone know if the code below is reasonable? Or is there a better way?

class Program
{
    public static void Main(string[] args)
    {
        var done = false;
        var load = new List&lt;byte[]&gt;();

        var pollGC = new Action(() =&gt;
        {
            // Register for a notification. 
            GC.RegisterForFullGCNotification(10, 10);
            Console.WriteLine("Registered for GC notification.");

            Stopwatch gcTimer = new Stopwatch();

            while (!done)
            {
                // Check for a notification of an approaching collection.
                GCNotificationStatus s = GC.WaitForFullGCApproach();
                if (s == GCNotificationStatus.Succeeded)
                {
                    Console.WriteLine("GC is about to start.");
                    load.Clear();
                    gcTimer.Restart();
                }

                // Check for a notification of a completed collection.
                s = GC.WaitForFullGCComplete();
                if (s == GCNotificationStatus.Succeeded)
                {
                    Console.WriteLine("GC has finished in {0} ms", gcTimer.ElapsedMilliseconds);
                }

                Thread.Sleep(500);
            }
            GC.CancelFullGCNotification();

            Console.WriteLine("Finished monitoring GC");

        });

        var doWork = new Action(() =&gt;
        {
            while (!done)
            {
                try
                {
                    load.Add(new byte[10000]);
                }
                catch (OutOfMemoryException)
                {
                    Console.WriteLine("Out of memory. {0}", load.Count);
                }
            }
        });

        Console.WriteLine(GCSettings.IsServerGC);

        Task.Run(pollGC);
        Task.Run(doWork);

        Console.ReadLine();
        done = true;
        GC.CancelFullGCNotification();

        Thread.Sleep(2000);
    }
}
For continuous monitoring I agree with Zer0 to look at the % time spent in GC performance counters.

However for a session based analysis a more informative approach would be to collect the ETW traces from .NET. You can see here for the different GC related events, GCStart and GCEnd would most likely be relevant for you.

view the .NET documentation for Garbage Collection ETW Events

You can specify the GC Collect Only option exists which would be very useful here. 


  The GC Collect Only Checkbox - Turns off all providers except those
  that describe garbage collections. Thus even the GC allocation
  sampling is turned off. This mode logs even less data than GC Only,
  and thus can collect data over an every longer period of time (say a
  day) in reasonable size (say 200 meg). The /GCCollectOnly command line
  option achieves the same effect.