public void CollectGcMetrics() { var logger = new TestLogger(LogLevel.Trace); string traceEventSessionName; using (var gcMetricsProvider = new GcMetricsProvider(logger)) { traceEventSessionName = gcMetricsProvider.TraceEventSessionName; gcMetricsProvider.IsMetricAlreadyCaptured.Should().BeFalse(); #if !NETCOREAPP2_1 //EventSource Microsoft-Windows-DotNETRuntime is only 2.2+, no gc metrics on 2.1 //repeat the allocation multiple times and make sure at least 1 GetSamples() call returns value // ReSharper disable once TooWideLocalVariableScope // ReSharper disable once RedundantAssignment var containsValue = false; var hasGenSize = false; var hasGcTime = false; for (var j = 0; j < 10; j++) { for (var i = 0; i < 500; i++) { var array = new int[10000000]; // In order to make sure the line above is not optimized away, let's use the array: Console.WriteLine($"GC test, int[] allocated with length: {array.Length}"); } GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForFullGCComplete(); GC.Collect(2, GCCollectionMode.Forced, true, true); for (var i = 0; i < 500; i++) { var array = new int[10000000]; // In order to make sure the line above is not optimized away, let's use the array: Console.WriteLine($"GC test, int[] allocated with length: {array.Length}"); } GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForFullGCComplete(); GC.Collect(2, GCCollectionMode.Forced, true, true); var samples = gcMetricsProvider.GetSamples()?.ToArray(); containsValue = samples != null && samples.Any(); hasGenSize = samples != null && samples .Any(n => (n.KeyValue.Key.Contains("gen0size") || n.KeyValue.Key.Contains("gen1size") || n.KeyValue.Key.Contains("gen2size") || n.KeyValue.Key.Contains("gen3size")) && n.KeyValue.Value > 0); hasGcTime = samples != null && samples .Any(n => n.KeyValue.Key.Contains("clr.gc.time") && n.KeyValue.Value > 0); if (containsValue && hasGenSize && hasGcTime) { break; } } if (PlatformDetection.IsDotNetFullFramework) { if (logger.Lines.Any(n => n.Contains("TraceEventSession initialization failed - GC metrics won't be collected"))) { // If initialization fails, (e.g. because ETW session initalization fails) we don't assert _output.WriteLine("Initialization failed. don't make assertions"); return; } } if (PlatformDetection.IsDotNetCore || PlatformDetection.IsDotNet5) { if (!logger.Lines.Any(n => n.Contains("OnEventWritten with GC"))) { // If no OnWritten with a GC event was called then initialization failed -> we don't assert _output.WriteLine("Initialization failed. don't make assertions"); return; } } containsValue.Should().BeTrue(); hasGenSize.Should().BeTrue(); hasGcTime.Should().BeTrue(); gcMetricsProvider.IsMetricAlreadyCaptured.Should().BeTrue(); #endif } if (PlatformDetection.IsDotNetFullFramework) { var traceEventSession = TraceEventSession.GetActiveSession(traceEventSessionName); traceEventSession.Should().BeNull(); } }
public void CollectGcMetrics() { var logger = new TestLogger(LogLevel.Trace); string traceEventSessionName; using (var gcMetricsProvider = new GcMetricsProvider(logger)) { traceEventSessionName = gcMetricsProvider.TraceEventSessionName; gcMetricsProvider.IsMetricAlreadyCaptured.Should().BeFalse(); #if !NETCOREAPP2_1 //EventSource Microsoft-Windows-DotNETRuntime is only 2.2+, no gc metrics on 2.1 //repeat the allocation multiple times and make sure at least 1 GetSamples() call returns value // ReSharper disable once TooWideLocalVariableScope // ReSharper disable once RedundantAssignment var containsValue = false; for (var j = 0; j < 1000; j++) { for (var i = 0; i < 300_000; i++) { var _ = new int[100]; } GC.Collect(); for (var i = 0; i < 300_000; i++) { var _ = new int[100]; } GC.Collect(); var samples = gcMetricsProvider.GetSamples(); containsValue = samples != null && samples.Any(); if (containsValue) { break; } } if (PlatformDetection.IsDotNetFullFramework) { if (logger.Lines.Any(n => n.Contains("TraceEventSession initialization failed - GC metrics won't be collected"))) { // If initialization fails, (e.g. because ETW session initalization fails) we don't assert _output.WriteLine("Initialization failed. don't make assertions"); return; } } if (PlatformDetection.IsDotNetCore || PlatformDetection.IsDotNet5) { if (!logger.Lines.Any(n => n.Contains("OnEventWritten with GC"))) { // If no OnWritten with a GC event was called then initialization failed -> we don't assert _output.WriteLine("Initialization failed. don't make assertions"); return; } } containsValue.Should().BeTrue(); gcMetricsProvider.IsMetricAlreadyCaptured.Should().BeTrue(); #endif } if (PlatformDetection.IsDotNetFullFramework) { var traceEventSession = TraceEventSession.GetActiveSession(traceEventSessionName); traceEventSession.Should().BeNull(); } }