private static void PrintDiagnosticInfo(DataTarget dt, ClrRuntime runtime, ClrHeap heap) { Console.WriteLine("DataTarget Info:"); Console.WriteLine(" ClrVersions: " + String.Join(", ", dt.ClrVersions)); Console.WriteLine(" IsMinidump: " + dt.IsMinidump); Console.WriteLine(" Architecture: " + dt.Architecture); Console.WriteLine(" PointerSize: " + dt.PointerSize); Console.WriteLine(" SymbolPath: " + dt.GetSymbolPath()); Console.WriteLine("ClrRuntime Info:"); Console.WriteLine(" ServerGC: " + runtime.ServerGC); Console.WriteLine(" HeapCount: " + runtime.HeapCount); Console.WriteLine(" Thread Count: " + runtime.Threads.Count); Console.WriteLine("ClrRuntime Modules:"); foreach (var module in runtime.EnumerateModules()) { Console.WriteLine(" {0,26} Id:{1}, {2,10:N0} bytes @ 0x{3:X8}", Path.GetFileName(module.FileName), module.AssemblyId, module.Size, module.ImageBase); } Console.WriteLine("ClrHeap Info:"); Console.WriteLine(" TotalHeapSize: " + heap.TotalHeapSize); Console.WriteLine(" Segments: " + heap.Segments.Count); Console.WriteLine(" Gen0 Size: " + heap.GetSizeByGen(0)); Console.WriteLine(" Gen1 Size: " + heap.GetSizeByGen(1)); Console.WriteLine(" Gen2 Size: " + heap.GetSizeByGen(2)); Console.WriteLine(" Gen3 Size: " + heap.GetSizeByGen(3)); }
private void PrintRuntimeDiagnosticInfo(DataTarget dataTarget, ClrRuntime runtime) { logger?.WriteLine(LogKind.Header, "\nRuntime Diagnostic Information"); logger?.WriteLine(LogKind.Header, "------------------------------"); logger?.WriteLine(LogKind.Header, "\nDataTarget Info:"); logger?.WriteLine(LogKind.Info, string.Format(" ClrVersion{0}: {1}", dataTarget.ClrVersions.Count > 1 ? "s" : "", string.Join(", ", dataTarget.ClrVersions))); logger?.WriteLine(LogKind.Info, " Architecture: " + dataTarget.Architecture); logger?.WriteLine(LogKind.Info, string.Format(" PointerSize: {0} ({1}-bit)", dataTarget.PointerSize, dataTarget.PointerSize == 8 ? 64 : 32)); logger?.WriteLine(LogKind.Info, " SymbolPath: " + dataTarget.GetSymbolPath()); logger?.WriteLine(LogKind.Header, "\nClrRuntime Info:"); logger?.WriteLine(LogKind.Info, " ServerGC: " + runtime.ServerGC); logger?.WriteLine(LogKind.Info, " HeapCount: " + runtime.HeapCount); logger?.WriteLine(LogKind.Info, " Thread Count: " + runtime.Threads.Count); logger?.WriteLine(LogKind.Header, "\nClrRuntime Modules:"); foreach (var module in runtime.EnumerateModules()) { logger?.WriteLine(LogKind.Info, string.Format( " {0,36} Id:{1} - {2,10:N0} bytes @ 0x{3:X16}", Path.GetFileName(module.FileName), module.AssemblyId.ToString().PadRight(10), module.Size, module.ImageBase)); } ClrHeap heap = runtime.GetHeap(); logger?.WriteLine(LogKind.Header, "\nClrHeap Info:"); logger?.WriteLine(LogKind.Info, string.Format(" TotalHeapSize: {0:N0} bytes ({1:N2} MB)", heap.TotalHeapSize, heap.TotalHeapSize / 1024.0 / 1024.0)); logger?.WriteLine(LogKind.Info, string.Format(" Gen0: {0,10:N0} bytes", heap.GetSizeByGen(0))); logger?.WriteLine(LogKind.Info, string.Format(" Gen1: {0,10:N0} bytes", heap.GetSizeByGen(1))); logger?.WriteLine(LogKind.Info, string.Format(" Gen2: {0,10:N0} bytes", heap.GetSizeByGen(2))); logger?.WriteLine(LogKind.Info, string.Format(" LOH: {0,10:N0} bytes", heap.GetSizeByGen(3))); logger?.WriteLine(LogKind.Info, " Segments: " + heap.Segments.Count); foreach (var segment in heap.Segments) { logger?.WriteLine(LogKind.Info, string.Format(" Segment: {0,10:N0} bytes, {1,10}, Gen0: {2,10:N0} bytes, Gen1: {3,10:N0} bytes, Gen2: {4,10:N0} bytes", segment.Length, segment.IsLarge ? "Large" : (segment.IsEphemeral ? "Ephemeral" : "Unknown"), segment.Gen0Length, segment.Gen1Length, segment.Gen2Length)); } logger?.WriteLine(); }
/// <summary> /// Get the size by generation 0, 1, 2, 3. The large object heap is Gen 3 here. /// The sum of all of these should add up to the TotalHeapSize. /// </summary> /// <param name="gen">The gen.</param> /// <returns>System.UInt64.</returns> /// <inheritdoc /> public ulong GetSizeByGen(int gen) => Heap.GetSizeByGen(gen);