public static bool WriteShortReport(StringStatsDispEntry[] entries, string reportPath, string title, int topItemCount, string[] sorts, string footer, out string error) { error = null; StreamWriter wr = null; try { wr = new StreamWriter(reportPath); var entriesCpy = new StringStatsDispEntry[entries.Length]; Array.Copy(entries, entriesCpy, entries.Length); wr.WriteLine(title); if (sorts.Contains("Count")) { wr.WriteLine(); wr.WriteLine(topItemCount + " top items by count, columns: [Count] | Size | Total Size | String Content"); Sort(entriesCpy, "Count"); for (int i = 0; i < topItemCount; ++i) { wr.Write(Utils.SizeStringHeader(entriesCpy[i].Count)); wr.Write(Utils.SizeString(entriesCpy[i].Size)); wr.Write(" " + Utils.SizeString(entriesCpy[i].TotSize) + " "); wr.WriteLine(ReportFile.GetReportLineString(entriesCpy[i].StrContent)); } } if (sorts.Contains("TotalSize")) { wr.WriteLine(); wr.WriteLine(topItemCount + " top items by total size, columns: Count | Size | [Total Size] | String Content"); Sort(entriesCpy, "TotalSize"); for (int i = 0; i < topItemCount; ++i) { wr.Write(Utils.SizeString(entriesCpy[i].Count) + " "); wr.Write(Utils.SizeString(entriesCpy[i].Size)); wr.Write(" " + Utils.SizeStringHeader(entriesCpy[i].TotSize) + " "); wr.WriteLine(ReportFile.GetReportLineString(entriesCpy[i].StrContent)); } } if (sorts.Contains("Size")) { wr.WriteLine(); wr.WriteLine(topItemCount + " top items by individual sizes, columns: Count | [Size] | Total Size | String Content"); Sort(entriesCpy, "Size"); for (int i = 0; i < topItemCount; ++i) { wr.Write(Utils.SizeString(entriesCpy[i].Count) + " "); wr.Write(Utils.SizeStringHeader(entriesCpy[i].Size)); wr.Write(" " + Utils.SizeString(entriesCpy[i].TotSize) + " "); wr.WriteLine(ReportFile.GetReportLineString(entriesCpy[i].StrContent)); } } if (string.IsNullOrWhiteSpace(footer)) { return(true); } wr.WriteLine(); wr.WriteLine(footer); return(true); } catch (Exception ex) { error = Utils.GetExceptionErrorString(ex); return(false); } finally { wr?.Close(); } }
public ListingInfo GetGridData(int minReferenceCount, ClrtSegment[] segments, out string error) { const int COLUMN_COUNT = 8; error = null; try { string[] dataAry; listing <string>[] itemAry; if (minReferenceCount < 1) { minReferenceCount = 1; } if (minReferenceCount < 2) { dataAry = new string[_strings.Length * COLUMN_COUNT]; itemAry = new listing <string> [dataAry.Length / COLUMN_COUNT]; int dataNdx = 0; for (int i = 0, icnt = _strings.Length; i < icnt; ++i) { var count = _counts[i]; var countStr = Utils.LargeNumberString(count); var size = _sizes[i]; var sizeStr = Utils.LargeNumberString(size); long totSize = (long)count * (long)size; var totSizeStr = Utils.LargeNumberString(totSize); var str = ReportFile.GetReportLineString(_strings[i]); var generations = ClrtSegment.GetGenerationHistogram(segments, _adddresses[i]); itemAry[i] = new listing <string>(dataAry, dataNdx, COLUMN_COUNT); dataAry[dataNdx++] = countStr; dataAry[dataNdx++] = sizeStr; dataAry[dataNdx++] = totSizeStr; dataAry[dataNdx++] = Utils.LargeNumberString(generations[0]); dataAry[dataNdx++] = Utils.LargeNumberString(generations[1]); dataAry[dataNdx++] = Utils.LargeNumberString(generations[2]); dataAry[dataNdx++] = Utils.LargeNumberString(generations[3]); dataAry[dataNdx++] = str; } } else { List <string> lst = new List <string>(_strings.Length); for (int i = 0, icnt = _strings.Length; i < icnt; ++i) { var count = _counts[i]; if (count < minReferenceCount) { continue; } var countStr = Utils.LargeNumberString(count); var size = _sizes[i]; var sizeStr = Utils.LargeNumberString(size); long totSize = (long)count * (long)size; var totSizeStr = Utils.LargeNumberString(totSize); var str = ReportFile.GetReportLineString(_strings[i]); var generations = ClrtSegment.GetGenerationHistogram(segments, _adddresses[i]); lst.Add(countStr); lst.Add(sizeStr); lst.Add(totSizeStr); lst.Add(Utils.LargeNumberString(generations[0])); lst.Add(Utils.LargeNumberString(generations[1])); lst.Add(Utils.LargeNumberString(generations[2])); lst.Add(Utils.LargeNumberString(generations[3])); lst.Add(str); } dataAry = lst.ToArray(); itemAry = new listing <string> [dataAry.Length / COLUMN_COUNT]; int dataNdx = 0; for (int i = 0, icnt = itemAry.Length; i < icnt; ++i) { itemAry[i] = new listing <string>(dataAry, dataNdx, COLUMN_COUNT); dataNdx += COLUMN_COUNT; } } StringBuilder sb = StringBuilderCache.Acquire(StringBuilderCache.MaxCapacity); sb.Append(ReportFile.DescrPrefix); sb.Append("String instance count: ") .Append(Utils.LargeNumberString(_totalCount)) .Append(", unique string count: ") .Append(Utils.LargeNumberString(_strings.Length)) .AppendLine(); sb.Append(ReportFile.DescrPrefix); sb.Append("Total size: ") .Append(Utils.LargeNumberString(_totalSize)) .Append(", total unique size: ") .Append(Utils.LargeNumberString(_totalUniqueSize)) .AppendLine(); sb.Append(ReportFile.DescrPrefix); sb.Append("Possible memory savings: ") .Append(Utils.LargeNumberString(_totalSize - _totalUniqueSize)) .AppendLine(); sb.Append(ReportFile.DescrPrefix); sb.Append("LISTING CONTAINS STRINGS WITH REFERENCE COUNT AT LEAST " + minReferenceCount) .Append(", DISPLAYED COUNT: ").Append(Utils.LargeNumberString(itemAry.Length)) .AppendLine(); ColumnInfo[] columns = { new ColumnInfo("Count", ReportFile.ColumnType.Int32, 100, 1, true), new ColumnInfo("Size", ReportFile.ColumnType.Int32, 100, 2, true), new ColumnInfo("Total Size", ReportFile.ColumnType.Int64, 100, 3, true), new ColumnInfo("Gen 0", ReportFile.ColumnType.Int64, 100, 4, true), new ColumnInfo("Gen 1", ReportFile.ColumnType.Int64, 100, 5, true), new ColumnInfo("Gen 2", ReportFile.ColumnType.Int64, 100, 6, true), new ColumnInfo("LOH", ReportFile.ColumnType.Int64, 100, 7, true), new ColumnInfo("String Content", ReportFile.ColumnType.String, 1500, 8, true), }; return(new ListingInfo(null, itemAry, columns, StringBuilderCache.GetStringAndRelease(sb))); } catch (Exception ex) { error = Utils.GetExceptionErrorString(ex); return(null); } }