private MemoryAnalyzer(DataTarget dataTarget) { // TODO: Exit gracefully for memory dumps from different platforms m_dataTarget = dataTarget; string dacLocation = m_dataTarget.ClrVersions[0].TryGetDacLocation(); if (String.IsNullOrEmpty(dacLocation)) throw new ArgumentException("Cannot find DAC location for process"); m_runtime = m_dataTarget.CreateRuntime(dacLocation); m_heap = m_runtime.GetHeap(); }
public ClrMDSession(DataTarget target, ClrRuntime runtime) { ClrMDSession.Detach(); Target = target; Runtime = runtime; Heap = Runtime.GetHeap(); m_allObjects = new Lazy<List<ClrObject>>(() => Heap.EnumerateClrObjects().ToList()); s_currentSession = this; }
public ClrHeapDecorator(ClrRuntime clrRuntime, ThreadDispatcher threadDispatcher) { _threadDispatcher = threadDispatcher; _clrHeap = threadDispatcher.Process(() => clrRuntime.GetHeap()); _threadDispatcher.Process(()=> { objectIndex = IndexBuilder.Build(_clrHeap); GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; }); }
private static IEnumerable<TypeHeapStat> GetHeapStatsByTypeForObjectSet(ClrRuntime clrRuntime, IEnumerable<ulong> objectIdSet) { ClrHeap heap = clrRuntime.GetHeap(); return from oid in objectIdSet let ot = heap.GetObjectType(oid) group oid by ot into objectTypeGroup let otSize = objectTypeGroup.Sum(oid => (uint)objectTypeGroup.Key.GetSize(oid)) select new TypeHeapStat { TypeName = objectTypeGroup.Key.Name, TotalHeapSize = otSize, NumberOfInstances = objectTypeGroup.Count() }; }
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, " ClrVersion{0}: {1}", dataTarget.ClrVersions.Count > 1 ? "s" : "", string.Join(", ", dataTarget.ClrVersions)); logger?.WriteLine(LogKind.Info, " Architecture: " + dataTarget.Architecture); logger?.WriteLine(LogKind.Info, " 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, " {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, " TotalHeapSize: {0:N0} bytes ({1:N2} MB)", heap.TotalHeapSize, heap.TotalHeapSize / 1024.0 / 1024.0); logger?.WriteLine(LogKind.Info, " Gen0: {0,10:N0} bytes", heap.GetSizeByGen(0)); logger?.WriteLine(LogKind.Info, " Gen1: {0,10:N0} bytes", heap.GetSizeByGen(1)); logger?.WriteLine(LogKind.Info, " Gen2: {0,10:N0} bytes", heap.GetSizeByGen(2)); logger?.WriteLine(LogKind.Info, " 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, " 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(); }
public static void PrintDict(ClrRuntime runtime, string args) { bool failed = false; ulong obj = 0; try { obj = Convert.ToUInt64(args, 16); failed = obj == 0; } catch (ArgumentException) { failed = true; } if (failed) { Console.WriteLine("Usage: !PrintDict <dictionary>"); return; } ClrHeap heap = runtime.GetHeap(); ClrType type = heap.GetObjectType(obj); if (type == null) { Console.WriteLine("Invalid object {0:X}", obj); return; } if (!type.Name.StartsWith("System.Collections.Generic.Dictionary")) { Console.WriteLine("Error: Expected object {0:X} to be a dictionary, instead it's of type '{1}'."); return; } // Get the entries field. ulong entries = type.GetFieldValue(obj, "entries"); if (entries == 0) return; ClrType entryArray = heap.GetObjectType(entries); ClrType arrayComponent = entryArray.ArrayComponentType; ClrInstanceField hashCodeField = arrayComponent.GetFieldByName("hashCode"); ClrInstanceField keyField = arrayComponent.GetFieldByName("key"); ClrInstanceField valueField = arrayComponent.GetFieldByName("value"); Console.WriteLine("{0,8} {1,16} : {2}", "hash", "key", "value"); int len = entryArray.GetArrayLength(entries); for (int i = 0; i < len; ++i) { ulong arrayElementAddr = entryArray.GetArrayElementAddress(entries, i); int hashCode = (int)hashCodeField.GetFieldValue(arrayElementAddr, true); object key = keyField.GetFieldValue(arrayElementAddr, true); object value = valueField.GetFieldValue(arrayElementAddr, true); key = Format(heap, key); value = Format(heap, value); bool skip = key is ulong && (ulong)key == 0 && value is ulong && (ulong)value == 0; if (!skip) Console.WriteLine("{0,8:X} {1,16} : {2}", hashCode, key, value); } }
private void TouchOtherRegions(DumpReaderLogger readerLogger, ClrRuntime runtime) { // Touch all threads, stacks, frames foreach (var t in runtime.Threads) { foreach (var f in t.StackTrace) { try { var ip = f.InstructionPointer; } catch (Exception) { } } } // Touch all modules runtime.Modules.Count(); // Touch all heap regions, roots, types var heap = runtime.GetHeap(); heap.EnumerateRoots(enumerateStatics: false).Count(); heap.EnumerateTypes().Count(); // TODO Check if it's faster to construct sorted inside ReaderWrapper foreach (var kvp in readerLogger.Ranges) _otherClrRegions.Add(kvp.Key, kvp.Value); }
private void CreateRuntime(int clrVersionIndex, string dacLocation) { _runtime = _target.ClrVersions[clrVersionIndex].CreateRuntime(dacLocation); _heap = _runtime.GetHeap(); }