예제 #1
0
        private static ObjectSet GetLiveObjects(ClrHeap heap)
        {
            ObjectSet     considered = new ObjectSet(heap);
            Stack <ulong> eval       = new Stack <ulong>();

            foreach (var root in heap.EnumerateRoots())
            {
                eval.Push(root.Object);
            }

            while (eval.Count > 0)
            {
                ulong obj = eval.Pop();
                if (considered.Contains(obj))
                {
                    continue;
                }

                considered.Add(obj);

                var type = heap.GetObjectType(obj);
                if (type == null)  // Only if heap corruption
                {
                    continue;
                }

                type.EnumerateRefsOfObject(obj, delegate(ulong child, int offset)
                {
                    if (child != 0 && !considered.Contains(child))
                    {
                        eval.Push(child);
                    }
                });
            }

            return(considered);
        }
예제 #2
0
        private static ObjectSet GetLiveObjects(ClrHeap heap)
        {
            ObjectSet considered = new ObjectSet(heap);
            Stack<ulong> eval = new Stack<ulong>();

            foreach (var root in heap.EnumerateRoots())
                eval.Push(root.Object);

            while (eval.Count > 0)
            {
                ulong obj = eval.Pop();
                if (considered.Contains(obj))
                    continue;

                considered.Add(obj);

                var type = heap.GetObjectType(obj);
                if (type == null)  // Only if heap corruption
                    continue;

                type.EnumerateRefsOfObject(obj, delegate(ulong child, int offset)
                {
                    if (child != 0 && !considered.Contains(child))
                        eval.Push(child);
                });
            }

            return considered;
        }
예제 #3
0
        static void Main(string[] args)
        {
            bool   stat, live;
            string dump, dac;

            if (!TryParseArgs(args, out dump, out dac, out stat, out live))
            {
                Usage();
                Environment.Exit(1);
            }

            try
            {
                ClrRuntime runtime = CreateRuntime(dump, dac);
                ClrHeap    heap    = runtime.GetHeap();

                ObjectSet liveObjs = null;
                if (live)
                {
                    liveObjs = GetLiveObjects(heap);
                }

                Dictionary <ClrType, Entry> stats = new Dictionary <ClrType, Entry>();

                if (!stat)
                {
                    Console.WriteLine("{0,16} {1,12} {2}", "Object", "Size", "Type");
                }

                foreach (ClrSegment seg in heap.Segments)
                {
                    for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj))
                    {
                        if (live && !liveObjs.Contains(obj))
                        {
                            continue;
                        }

                        // This gets the type of the object.
                        ClrType type = heap.GetObjectType(obj);
                        ulong   size = type.GetSize(obj);

                        // If the user didn't request "-stat", print out the object.
                        if (!stat)
                        {
                            Console.WriteLine("{0,16:X} {1,12:n0} {2}", obj, size, type.Name);
                        }

                        // Add an entry to the dictionary, if one doesn't already exist.
                        Entry entry = null;
                        if (!stats.TryGetValue(type, out entry))
                        {
                            entry       = new Entry();
                            entry.Name  = type.Name;
                            stats[type] = entry;
                        }

                        // Update the statistics for this object.
                        entry.Count++;
                        entry.Size += type.GetSize(obj);
                    }
                }

                // Now print out statistics.
                if (!stat)
                {
                    Console.WriteLine();
                }

                // We'll actually let linq do the heavy lifting.
                var sortedStats = from entry in stats.Values
                                  orderby entry.Size
                                  select entry;

                ulong totalSize = 0, totalCount = 0;
                Console.WriteLine("{0,12} {1,12} {2}", "Size", "Count", "Type");
                foreach (var entry in sortedStats)
                {
                    Console.WriteLine("{0,12:n0} {1,12:n0} {2}", entry.Size, entry.Count, entry.Name);
                    totalSize  += entry.Size;
                    totalCount += (uint)entry.Count;
                }

                Console.WriteLine();
                Console.WriteLine("Total: {0:n0} bytes in {1:n0} objects", totalSize, totalCount);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unhandled exception:");
                Console.WriteLine(ex);
            }
        }