in Microsoft.Diagnostics.Tracing/TraceEvent/TraceEvent/20_ObserveGCEvent.cs [20:84]
public static void Run()
{
Out.WriteLine("******************** ObserveGCEvents DEMO ********************");
Out.WriteLine("This program Demos using the reactive framework (IObservable) to monitor");
Out.WriteLine(".NET Garbage collector (GC) events.");
Out.WriteLine();
Out.WriteLine("The program will print a line every time 100K of memory was allocated");
Out.WriteLine("on the GC heap along with the type of the object that 'tripped' the 100K");
Out.WriteLine("sample. It will also print a line every time a GC happened and show ");
Out.WriteLine("the sizes of each generation after the GC.");
Out.WriteLine();
Out.WriteLine("Run a .NET Program while the monitoring is active to see GC events.");
Out.WriteLine();
if (TraceEventSession.IsElevated() != true)
{
Out.WriteLine("Must be elevated (Admin) to run this method.");
Debugger.Break();
return;
}
var monitoringTimeSec = 10;
Out.WriteLine("The monitor will run for a maximum of {0} seconds", monitoringTimeSec);
Out.WriteLine("Press Ctrl-C to stop monitoring of GC Allocs");
// create a real time user mode session
using (var userSession = new TraceEventSession("ObserveGCAllocs"))
{
// Set up Ctrl-C to stop the session
SetupCtrlCHandler(() => { userSession.Stop(); });
// enable the CLR provider with default keywords (minus the rundown CLR events)
userSession.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,
(ulong)(ClrTraceEventParser.Keywords.GC));
// Create a stream of GC Allocation events (happens every time 100K of allocations happen)
IObservable<GCAllocationTickTraceData> gcAllocStream = userSession.Source.Clr.Observe<GCAllocationTickTraceData>();
// Print the outgoing stream to the console
gcAllocStream.Subscribe(allocData =>
Out.WriteLine("GC Alloc : Proc: {0,10} Amount: {1,6:f1}K TypeSample: {2}", GetProcessName(allocData.ProcessID), allocData.AllocationAmount / 1000.0, allocData.TypeName));
// Create a stream of GC Collection events
IObservable<GCHeapStatsTraceData> gcCollectStream = userSession.Source.Clr.Observe<GCHeapStatsTraceData>();
// Print the outgoing stream to the console
gcCollectStream.Subscribe(collectData =>
Out.WriteLine("GC Collect: Proc: {0,10} Gen0: {1,6:f1}M Gen1: {2,6:f1}M Gen2: {3,6:f1}M LargeObj: {4,6:f1}M",
GetProcessName(collectData.ProcessID),
collectData.GenerationSize0 / 1000000.0,
collectData.GenerationSize1 / 1000000.0,
collectData.GenerationSize2 / 1000000.0,
collectData.GenerationSize3 / 1000000.0));
IObservable<long> timer = Observable.Timer(new TimeSpan(0, 0, monitoringTimeSec));
timer.Subscribe(delegate
{
Out.WriteLine("Stopped after {0} sec", monitoringTimeSec);
userSession.Dispose();
});
// OK we are all set up, time to listen for events and pass them to the observers.
userSession.Source.Process();
}
Out.WriteLine("Done with program.");
}