private bool IsFilteredType(TypeEntry typeEntry)
        {
            string key = HeapSnapshot.GetKey(typeEntry);

            return
                (_filteredEntries.Any(e => (string.Compare(HeapSnapshot.GetKey(e), key) == 0)));
        }
 private TypeEntryListViewItem GetItemFromEntry(ListView listview, TypeEntry entry)
 {
     foreach (TypeEntryListViewItem item in listview.Items)
     {
         TypeEntry tagEntry = (TypeEntry)item.Tag;
         if (string.Compare(HeapSnapshot.GetKey(tagEntry), HeapSnapshot.GetKey(entry)) == 0)
         {
             return(item);
         }
     }
     return(null);
 }
        public static HeapSnapshot Compare(HeapSnapshot reference, HeapSnapshot current)
        {
            HeapSnapshot compare = new HeapSnapshot();

            // loop on each entry in the current snapshot and compare with the reference
            foreach (var item in current.TypeStats)
            {
                // look for this class in the reference
                if (reference.TypeStats.ContainsKey(item.Key))
                {
                    TypeEntry referenceEntry = reference.TypeStats[item.Key];
                    if (referenceEntry.Count < item.Value.Count)
                    {
                        var entry = new TypeEntry();
                        entry.Name        = string.Intern(referenceEntry.Name);
                        entry.MethodTable = referenceEntry.MethodTable;
                        entry.Count       = item.Value.Count - referenceEntry.Count;
                        entry.TotalSize   = item.Value.TotalSize - referenceEntry.TotalSize;

                        compare.TypeStats.Add(HeapSnapshot.GetKey(entry), entry);

                        compare.ObjectCount += entry.Count;
                        compare.Size        += entry.TotalSize;
                    }
                }
                else  // don't forget the case where brand new type instances appear in current snapshot
                {
                    var entry = new TypeEntry();
                    entry.Name        = string.Intern(item.Value.Name);
                    entry.MethodTable = item.Value.MethodTable;
                    entry.Count       = item.Value.Count;
                    entry.TotalSize   = item.Value.TotalSize;

                    compare.TypeStats.Add(HeapSnapshot.GetKey(entry), entry);

                    compare.ObjectCount += entry.Count;
                    compare.Size        += entry.TotalSize;
                }
            }

            return(compare);
        }
Exemple #4
0
        private static HeapSnapshot Compute(ClrHeap heap)
        {
            var snapshot = new HeapSnapshot();

            foreach (ulong objAddress in heap.EnumerateObjectAddresses())
            {
                ClrType type = heap.GetObjectType(objAddress);
                if (type == null)
                {
                    continue;
                }

                var mt   = type.MethodTable.ToString();
                var name = type.Name;
                var key  = HeapSnapshot.GetKey(name, mt);

                if (!snapshot.TypeStats.TryGetValue(key, out var entry))
                {
                    entry = new TypeEntry()
                    {
                        Name        = name,
                        MethodTable = mt
                    };

                    snapshot.TypeStats[key] = entry;
                }
                entry.Count          = entry.Count + 1;
                snapshot.ObjectCount = snapshot.ObjectCount + 1;

                var size = type.GetSize(objAddress);
                entry.TotalSize = entry.TotalSize + (long)size;
                snapshot.Size   = snapshot.Size + (long)size;
            }

            return(snapshot);
        }
        private static DumpHeapParsingState ParseAndAddTypeEntry(string line, HeapSnapshot snapshot)
        {
            if (line.StartsWith("Total"))
            {
                return(DumpHeapParsingState.End);
            }

            //       MT    Count    TotalSize Class Name
            // 651d7ffc        1           12 System.Configuration.Internal.ConfigurationManagerInternal
            //
            // or in x64
            //
            // 0x000007ff01221408    1,448       57,920 System.Xml.XmlQualifiedName
            //
            TypeEntry entry = new TypeEntry();
            var       pos   = 0;
            var       end   = 0;
            string    field;

            // 1. look for the MT
            end = line.IndexOf(SPACE);
            if (end == -1)
            {
                Debug.WriteLine("impossible to find the end of the MT field");
                return(DumpHeapParsingState.Error);
            }
            field             = line.Substring(pos, end - pos);
            entry.MethodTable = field;

            if (!SkipSpaces(line, ref end))
            {
                Debug.WriteLine("impossible to find the start of the Count field");
                return(DumpHeapParsingState.Error);
            }
            pos = end;

            // 2. look for the count
            end = line.IndexOf(SPACE, pos);
            if (end == -1)
            {
                Debug.WriteLine("impossible to find the end of the Count field");
                return(DumpHeapParsingState.Error);
            }
            field = line.Substring(pos, end - pos);

            if (!long.TryParse(GetNumberFromString(field), out var count))
            {
                Debug.WriteLine("invalid decimal value for the Count field");
                return(DumpHeapParsingState.Error);
            }
            entry.Count = count;

            if (!SkipSpaces(line, ref end))
            {
                Debug.WriteLine("impossible to find the start of the TotalSize field");
                return(DumpHeapParsingState.Error);
            }
            pos = end;


            // 3. look for the total size
            end = line.IndexOf(SPACE, pos);
            if (end == -1)
            {
                Debug.WriteLine("impossible to find the end of the MT field");
                return(DumpHeapParsingState.Error);
            }
            field = line.Substring(pos, end - pos);
            if (!long.TryParse(GetNumberFromString(field), out var totalSize))
            {
                Debug.WriteLine("invalid decimal value for the TotalSize field");
                return(DumpHeapParsingState.Error);
            }
            entry.TotalSize = totalSize;

            if (!SkipSpaces(line, ref end))
            {
                Debug.WriteLine("impossible to find the start of the TotalSize field");
                return(DumpHeapParsingState.Error);
            }
            pos = end;


            // 4. look for the class name
            field      = line.Substring(pos);
            entry.Name = string.Intern(field);

            snapshot.ObjectCount += entry.Count;
            snapshot.Size        += entry.TotalSize;

            string key = HeapSnapshot.GetKey(entry);

            if (!snapshot.TypeStats.ContainsKey(key))
            {
                snapshot.TypeStats.Add(key, entry);
            }
            else
            {
                Debug.Fail("This should never happen");
                throw new InvalidOperationException($"Impossible to find {key} for the entry");
            }

            return(DumpHeapParsingState.TypeEntries);
        }