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<byte[]>();
var pollGC = new Action(() =>
{
// 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(() =>
{
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);
}
}