static void Main(string[] args) { string dump, dac; if (!TryParseArgs(args, out dump, out dac)) { Usage(); Environment.Exit(1); } try { // Create a ClrRuntime instance from the dump and dac location. The ClrRuntime // object represents a version of CLR loaded in the process. It contains data // such as the managed threads in the process, the AppDomains in the process, // the managed heap, and so on. ClrRuntime runtime = CreateRuntime(dump, dac); // To get memory statistics, you can use EnumerateMemoryRegions. This enumerates // the address and size of every memory region (I.E., heap) that CLR allocates. // You can use this information to track down what's "too large" in your process. Dictionary<ClrMemoryRegionType, Entry> stats = new Dictionary<ClrMemoryRegionType, Entry>(); foreach (var region in runtime.EnumerateMemoryRegions()) { Entry entry; if (!stats.TryGetValue(region.Type, out entry)) { entry = new Entry(); stats[region.Type] = entry; } entry.Regions.Add(region); entry.Size += region.Size; } // Print out total stats var sortedEntries = from t in stats.Values orderby t.Size select t; Console.WriteLine("Total stats for {0} AppDomain{1}:", runtime.AppDomains.Count, runtime.AppDomains.Count > 1 ? "s" : ""); Console.WriteLine("{0,12} {1}", "Size", "Memory Type"); foreach (var entry in sortedEntries) Console.WriteLine("{0,12:n0} {1}", entry.Size, entry.Name); // Print out per-appdomain usage. You could probably get more clever with linq here, // but I tried to keep this as simple as possible. foreach (ClrAppDomain ad in runtime.AppDomains) { Console.WriteLine(); Console.WriteLine("Memory usage for AppDomain '{0}':", ad.Name); foreach (Entry entry in stats.Values) { if (!entry.HasAppDomainData) continue; long size = entry.Regions.Where(p => p.AppDomain == ad).Sum(p => (uint)p.Size); if (size > 0) Console.WriteLine("{0,12:n0} {1}", size, entry.Name); } } } catch (Exception ex) { Console.WriteLine("Unhandled exception:"); Console.WriteLine(ex); } }
public ObjectSet(ClrHeap heap) { m_shift = IntPtr.Size == 4 ? 3 : 4; int count = heap.Segments.Count; m_data = new BitArray[count]; m_entries = new Entry[count]; #if DEBUG ulong last = 0; #endif for (int i = 0; i < count; ++i) { var seg = heap.Segments[i]; #if DEBUG Debug.Assert(last < seg.Start); last = seg.Start; #endif m_data[i] = new BitArray(GetBitOffset(seg.Length)); m_entries[i].Low = seg.Start; m_entries[i].High = seg.End; m_entries[i].Index = i; } }