private void DumpHeapStatsByType(long minSize, long maxSize, string typeName, IEnumerable<TypeHeapStat> typeHeapStats)
{
IEnumerable<TypeHeapStat> filteredResults = typeHeapStats;
if(minSize > 0)
{
filteredResults = filteredResults.Where(ths => ths.TotalHeapSize >= minSize);
}
if(maxSize > 0)
{
filteredResults = filteredResults.Where(ths => ths.TotalHeapSize <= maxSize);
}
bool typeFilterSpecified = !string.IsNullOrWhiteSpace(typeName);
if(typeFilterSpecified)
{
filteredResults = filteredResults.Where(ths => ths.TypeName.StartsWith(typeName.Trim()));
}
filteredResults = filteredResults.OrderBy(ths => ths.TotalHeapSize);
List<TypeHeapStat> bufferedFilteredResults = filteredResults.ToList();
this.outputWriter.WriteLine("Heap Stats By Type");
this.outputWriter.WriteLineSeparator();
this.outputWriter.WriteLine("Filter options:");
this.outputWriter.WriteLine(" Min Heap Size: {0}", minSize);
this.outputWriter.WriteLine(" Max Heap Size: {0}", maxSize == 0 ? "<unbounded>" : maxSize.ToString());
this.outputWriter.WriteLine(" Type filter: {0}", typeFilterSpecified ? typeName : "<none>");
this.outputWriter.WriteLine(string.Empty);
foreach(TypeHeapStat typeHeapStat in bufferedFilteredResults)
{
this.outputWriter.WriteLine("{0,12:n0} {1,12:n0} {2}", typeHeapStat.TotalHeapSize, typeHeapStat.NumberOfInstances, typeHeapStat.TypeName);
}
this.outputWriter.WriteLineSeparator();
if(typeFilterSpecified)
{
this.outputWriter.WriteLine("Total # of types matching filter: {0:n0}", bufferedFilteredResults.Count);
this.outputWriter.WriteLine("Total size of filtered objects: {0:n0}", bufferedFilteredResults.Sum(ths => ths.TotalHeapSize));
}
ClrHeap clrHeap = this.currentClrRuntime.GetHeap();
this.outputWriter.WriteLine("Total Heap Size: {0:n0}", clrHeap.TotalHeapSize);
;
this.outputWriter.WriteLine("(Gen 0: {1:n0}, Gen 1: {1:n0}; Gen 2: {2:n0}; Gen 3: {3:n0})", clrHeap.GetSizeByGen(0), clrHeap.GetSizeByGen(1), clrHeap.GetSizeByGen(2), clrHeap.GetSizeByGen(3));
}
}