internal static void HeapDumpReport(string logFileName, string startMarker, string endMarker) { ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); Histogram[] heapDumpHistograms = entireLogResult.heapDumpHistograms; string[] timeMarkers = new String[heapDumpHistograms.Length]; if (startMarker != null || endMarker != null) { int startTickIndex = 0; int endTickIndex = entireLogResult.sampleObjectTable.lastTickIndex; if (startMarker != null) { startTickIndex = FindMarkerTickIndex(startMarker, log); } if (endMarker != null) { endTickIndex = FindMarkerTickIndex(endMarker, log); } int startIndex = 0; int endIndex = 0; for (int i = 0; i < log.heapDumpEventList.count; i++) { if (log.heapDumpEventList.eventTickIndex[i] < startTickIndex) { startIndex = i + 1; } if (log.heapDumpEventList.eventTickIndex[i] < endTickIndex) { endIndex = i + 1; } } if (endMarker == null) { Console.WriteLine("Heap dump for {0} after {1}", logFileName, startMarker); if (startIndex < log.heapDumpEventList.count) { endIndex = startIndex + 1; } else { endIndex = startIndex; } } else { Console.WriteLine("Heap dump for {0} between {1} and {2}", logFileName, startMarker, endMarker); } if (startIndex < endIndex) { heapDumpHistograms = new Histogram[endIndex - startIndex]; for (int i = startIndex; i < endIndex; i++) { heapDumpHistograms[i - startIndex] = entireLogResult.heapDumpHistograms[i]; } timeMarkers = new string[endIndex - startIndex]; } else { heapDumpHistograms = new Histogram[0]; timeMarkers = new string[0]; } } else { Console.WriteLine("Heap dumps for {0}", logFileName); } for (int i = 0; i < timeMarkers.Length; i++) { timeMarkers[i] = string.Format("Heap dump #{0}", i); } if (heapDumpHistograms.Length > 0) { WriteReport(heapDumpHistograms, timeMarkers); } else { Console.WriteLine("***** No heap dumps found *****"); } }
internal void UpdateObjects(Histogram relocatedHistogram, ulong oldId, ulong newId, uint length, int tickIndex, SampleObjectTable sampleObjectTable) { if (lastPos >= readNewLog.pos) return; lastPos = readNewLog.pos; lastTickIndex = tickIndex; intervalTable.Relocate(oldId, newId, length); if (oldId == newId) return; ulong nextId; ulong lastId = oldId + length; LiveObject o; for (GetNextObject(oldId, lastId, out o); o.id < lastId; GetNextObject(nextId, lastId, out o)) { nextId = o.id + o.size; ulong offset = o.id - oldId; if (sampleObjectTable != null) sampleObjectTable.Delete(o.id, o.id + o.size, tickIndex); Zero(o.id, o.size); InsertObject(newId + offset, o.typeSizeStacktraceIndex, o.allocTickIndex, tickIndex, false, sampleObjectTable); if (relocatedHistogram != null) relocatedHistogram.AddObject(o.typeSizeStacktraceIndex, 1); } }
private static void WriteReport(Histogram histogram, string timeMarker) { WriteReport(new Histogram[1] { histogram }, new string[1] { timeMarker } ); }
private void showAllocatorsMenuItem_Click(object sender, System.EventArgs e) { TypeDesc selectedType = FindSelectedType(); // Create a new allocation graph and add all the objects in the selected address range // whose type matches the selected type (if any). ReadNewLog log = liveObjectTable.readNewLog; Histogram histogram = new Histogram(log); ulong low = selectedLowAddr; ulong high = low == 0 ? ulong.MaxValue : selectedHighAddr; LiveObjectTable.LiveObject o; for (liveObjectTable.GetNextObject(low, high, out o); o.id < high; liveObjectTable.GetNextObject(o.id + o.size, high, out o)) { if (selectedType == null || selectedType.typeIndex == o.typeIndex) histogram.AddObject(o.typeSizeStacktraceIndex, 1); } // Build the real graph from the histogram Graph graph = histogram.BuildAllocationGraph(new FilterForm()); // And make another graph form for it - hardest part is to compute an appropriate title... string title = "Allocation Graph for live " + ComputeObjectsDescription(selectedType, selectedLowAddr, selectedHighAddr); GraphViewForm graphViewForm = new GraphViewForm(graph, title); graphViewForm.Visible = true; }
private static void FillHistogramIntoDiffTypeDescriptor(Histogram histogram, DiffTypeDescriptor[] typeIndexToDiffTypeDescriptor) { for (int i = 0; i < histogram.typeSizeStacktraceToCount.Length; i++) { int count = histogram.typeSizeStacktraceToCount[i]; if (count == 0) continue; int[] stacktrace = histogram.readNewLog.stacktraceTable.IndexToStacktrace(i); int typeIndex = stacktrace[0]; int size = stacktrace[1]; if (typeIndexToDiffTypeDescriptor[typeIndex] == null) typeIndexToDiffTypeDescriptor[typeIndex] = new DiffTypeDescriptor(typeIndex); typeIndexToDiffTypeDescriptor[typeIndex].bSize += size*count; typeIndexToDiffTypeDescriptor[typeIndex].diffSize += size*count; typeIndexToDiffTypeDescriptor[typeIndex].bCount += count; typeIndexToDiffTypeDescriptor[typeIndex].diffCount += count; } }
/// <summary> /// Sonal: Function to generate and print Leak Report for the dump file. /// </summary> /// <param name="logFileName">dump file name</param> /// <param name="startMarker">int {0,NumHeapDumps}</param> /// <param name="endMarker">int {0,NumHeapDumps}</param> internal static void LeakReport(string logFileName, string startMarker, string endMarker) { if (startMarker == null) startMarker = "1"; if (endMarker == null) endMarker = "2"; int startIndex; int endIndex; try { startIndex = int.Parse(startMarker); endIndex = int.Parse(endMarker); } catch { throw new ArgumentException("Markers have to be positive integral values"); } startIndex--; endIndex--; if ((startIndex < 0) || (endIndex < 0)) { throw new ArgumentException("Markers can not be negative"); } ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult, endIndex + 1); if (entireLogResult.requestedObjectGraph == null) { throw new ArgumentException("Invalid EndIndex"); } Histogram[] heapDumpHistograms = entireLogResult.heapDumpHistograms; string[] timeMarkers = new String[2]; if (startIndex < endIndex) { heapDumpHistograms = new Histogram[endIndex - startIndex + 1]; for (int i = startIndex; i <= endIndex; i++) { heapDumpHistograms[i - startIndex] = entireLogResult.heapDumpHistograms[i]; } timeMarkers = new string[endIndex - startIndex + 1]; } else { heapDumpHistograms = new Histogram[0]; timeMarkers = new string[0]; } for (int i = 0; i < timeMarkers.Length; i++) { timeMarkers[i] = string.Format("Heap dump #{0}", i + 1); } if (heapDumpHistograms.Length > 0) WriteDiffReport(heapDumpHistograms, timeMarkers, entireLogResult); else Console.WriteLine("***** No heap dumps found *****"); }
private void CreateHandleAllocationGraph(Histogram histogram, string title) { Graph graph = histogram.BuildHandleAllocationGraph(new FilterForm()); graph.graphType = Graph.GraphType.HandleAllocationGraph; GraphViewForm graphViewForm = new GraphViewForm(graph, title); graphViewForm.Show(); }
internal static Histogram GetSurvivorHistogram(ReadNewLog log, ReadLogResult entireLogResult, int startTickIndex, int endTickIndex, string timeMarker) { ReadLogResult logResult = entireLogResult; int timeTickIndex = entireLogResult.sampleObjectTable.lastTickIndex; if (timeMarker != null) { timeTickIndex = FindMarkerTickIndex(timeMarker, log); long endPos = log.TickIndexToPos(timeTickIndex); // Read the selected portion of the log again logResult = new ReadLogResult(); logResult.liveObjectTable = new LiveObjectTable(log); log.ReadFile(0, endPos, logResult); } Histogram histogram = new Histogram(log); LiveObjectTable.LiveObject o; for (logResult.liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue; logResult.liveObjectTable.GetNextObject(o.id + o.size, ulong.MaxValue, out o)) { if (startTickIndex <= o.allocTickIndex && o.allocTickIndex < endTickIndex) histogram.AddObject(o.typeSizeStacktraceIndex, 1); } return histogram; }
internal HistogramViewForm(Histogram histogram, string title) : this() { this.histogram = histogram; autoUpdate = false; Text = title; }
private Histogram GetLiveHistogram() { LiveObjectTable liveObjectTable = GetLiveObjectTable(); Histogram histogram = new Histogram(sampleObjectTable.readNewLog); LiveObjectTable.LiveObject o; for (liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue; liveObjectTable.GetNextObject(o.id + o.size, ulong.MaxValue, out o)) { if (firstAllocTickIndex <= o.allocTickIndex && o.allocTickIndex < lastAllocTickIndex) histogram.AddObject(o.typeSizeStacktraceIndex, 1); } return histogram; }
private void showWhoAllocatedMenuItem_Click(object sender, System.EventArgs e) { Histogram selectedHistogram; string title; TypeDesc selectedType = FindSelectedType(); if (selectedType == null) { title = "Allocation Graph"; selectedHistogram = histogram; } else { int minSize = 0; int maxSize = int.MaxValue; foreach (Bucket b in buckets) { if (b.selected) { minSize = b.minSize; maxSize = b.maxSize; } } title = string.Format("Allocation Graph for {0} objects", selectedType.typeName); if (minSize > 0) title += string.Format(" of size between {0:n0} and {1:n0} bytes", minSize, maxSize); selectedHistogram = new Histogram(histogram.readNewLog); for (int i = 0; i < histogram.typeSizeStacktraceToCount.Length; i++) { int count = histogram.typeSizeStacktraceToCount[i]; if (count > 0) { int[] stacktrace = histogram.readNewLog.stacktraceTable.IndexToStacktrace(i); int typeIndex = stacktrace[0]; int size = stacktrace[1]; if (minSize <= size && size <= maxSize) { TypeDesc t = (TypeDesc)typeIndexToTypeDesc[typeIndex]; if (t == selectedType) { selectedHistogram.AddObject(i, count); } } } } } Graph graph = selectedHistogram.BuildAllocationGraph(new FilterForm()); GraphViewForm graphViewForm = new GraphViewForm(graph, title); graphViewForm.Visible = true; }
private void versionTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (font != MainForm.instance.font) { font = MainForm.instance.font; graphPanel.Invalidate(); typeLegendPanel.Invalidate(); } ReadLogResult readLogResult = MainForm.instance.lastLogResult; if (autoUpdate && readLogResult != null && readLogResult.allocatedHistogram != histogram) { histogram = readLogResult.allocatedHistogram; typeName = histogram.readNewLog.typeName; graphPanel.Invalidate(); typeLegendPanel.Invalidate(); } }
internal void ReportCallCountSizes(Histogram callstackHistogram) { uint[] callCount = new uint[readNewLog.funcName.Length]; callstackHistogram.CalculateCallCounts(callCount); Console.WriteLine("{0},{1},{2} {3}", "# Calls", "Function Size", "Function Name", "Function Signature"); foreach (FunctionDescriptor fd in functionList) { Console.WriteLine("{0},{1},{2} {3}", callCount[fd.functionId], fd.funcSize, readNewLog.funcName[fd.functionId], readNewLog.funcSignature[fd.functionId]); } }
private void survingHandlesAllocationGraphButton_Click(object sender, System.EventArgs e) { Histogram histogram = new Histogram(log); foreach (HandleInfo handleInfo in logResult.handleHash.Values) { histogram.AddObject(handleInfo.allocStacktraceId, 1); } string title = "Surviving Handle Allocation Graph for: " + scenario; CreateHandleAllocationGraph(histogram, title); }
/// <summary> /// Added by Sonal: /// Writes Difference between two heap dumps /// </summary> /// <param name="histogram"></param> /// <param name="timeMarker"></param> private static void WriteDiffReport(Histogram[] histogram, string[] timeMarker, ReadLogResult entireLogResult) { TypeDescriptor[] typeIndexToTypeDescriptor = new TypeDescriptor[histogram[0].readNewLog.typeName.Length]; int[] totalSize = new int[histogram.Length]; int[] totalCount = new int[histogram.Length]; for (int h = 0; h < histogram.Length; h++) { int[] typeSizeStacktraceToCount = histogram[h].typeSizeStacktraceToCount; for (int i = 0; i < typeSizeStacktraceToCount.Length; i++) { int count = typeSizeStacktraceToCount[i]; if (count == 0) continue; int[] stacktrace = histogram[h].readNewLog.stacktraceTable.IndexToStacktrace(i); int typeIndex = stacktrace[0]; int size = stacktrace[1]; if (typeIndexToTypeDescriptor[typeIndex] == null) typeIndexToTypeDescriptor[typeIndex] = new TypeDescriptor(typeIndex, histogram.Length); typeIndexToTypeDescriptor[typeIndex].size[h] += size * count; typeIndexToTypeDescriptor[typeIndex].count[h] += count; totalSize[h] += size * count; totalCount[h] += count; } } ArrayList al = new ArrayList(); for (int i = 0; i < typeIndexToTypeDescriptor.Length; i++) { if (typeIndexToTypeDescriptor[i] == null) continue; al.Add(typeIndexToTypeDescriptor[i]); } al.Sort(); Console.WriteLine("<?xml version=\"1.0\"?>"); Console.WriteLine("<DetailedLeakReport>"); Console.WriteLine("<LeakSummary>"); int counter = 0; foreach (TypeDescriptor td in al) { int diffCount = td.count[histogram.Length - 1] - td.count[0]; int diffSize = td.size[histogram.Length - 1] - td.size[0]; if (diffCount > 0) { counter++; Console.WriteLine("<Object>"); Console.WriteLine("<Counter>{0}</Counter>", counter); Console.WriteLine("<ObjectName><!--{0}--></ObjectName>", histogram[0].readNewLog.typeName[td.typeIndex]); for (int h = 0; h < histogram.Length; h++) { Console.WriteLine("<CheckPoint{0}>", h + 1); Console.WriteLine("<Instances>{0}</Instances>", td.count[h]); Console.WriteLine("<Size>{0}</Size>", td.size[h]); Console.WriteLine("</CheckPoint{0}>", h + 1); } Console.WriteLine("<Difference>"); Console.WriteLine("<Instances>{0}</Instances>", diffCount); Console.WriteLine("<Size>{0}</Size>", diffSize); Console.WriteLine("</Difference>"); Console.WriteLine("</Object>"); } } Console.WriteLine("</LeakSummary>"); Console.WriteLine("<LeakDetails>"); counter = 0; foreach (TypeDescriptor td in al) { int diffCount = td.count[histogram.Length - 1] - td.count[0]; int diffSize = td.size[histogram.Length - 1] - td.size[0]; if (diffCount > 0) { counter++; Console.WriteLine("<LeakedObject>"); Console.WriteLine("<Summary>"); Console.WriteLine("<Counter>{0}</Counter>", counter); Console.WriteLine("<ObjectName><!--{0}--></ObjectName>", histogram[0].readNewLog.typeName[td.typeIndex]); for (int h = 0; h < histogram.Length; h++) { Console.WriteLine("<CheckPoint{0}>", h + 1); Console.WriteLine("<Instances>{0}</Instances>", td.count[h]); Console.WriteLine("<Size>{0}</Size>", td.size[h]); Console.WriteLine("</CheckPoint{0}>", h + 1); } Console.WriteLine("<Difference>"); Console.WriteLine("<Instances>{0}</Instances>", diffCount); Console.WriteLine("<Size>{0}</Size>", diffSize); if (entireLogResult.requestedObjectGraph != null) entireLogResult.requestedObjectGraph.WriteVertexPaths(histogram[0].tickIndex, histogram[histogram.Length - 1].tickIndex, histogram[0].readNewLog.typeName[td.typeIndex]); else if (entireLogResult.objectGraph != null) entireLogResult.objectGraph.WriteVertexPaths(histogram[0].tickIndex, histogram[histogram.Length - 1].tickIndex, histogram[0].readNewLog.typeName[td.typeIndex]); Console.WriteLine("</LeakedObject>"); } } Console.WriteLine("</LeakDetails>"); Console.WriteLine("</DetailedLeakReport>"); }
private string CalculateTotalCount(Histogram histogram) { double totalCount = 0.0; for (int i = 0; i < histogram.typeSizeStacktraceToCount.Length; i++) { int count = histogram.typeSizeStacktraceToCount[i]; totalCount += count; } return FormatNumber(totalCount); }
internal static void SurvivorReport(string logFileName, string startMarker, string endMarker, string[] timeMarker) { // first read the entire file ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); if (startMarker == null) startMarker = CommentRangeForm.startCommentString; if (endMarker == null) endMarker = CommentRangeForm.shutdownCommentString; int startTickIndex = FindMarkerTickIndex(startMarker, log); int endTickIndex = FindMarkerTickIndex(endMarker, log); if (timeMarker == null || timeMarker.Length == 0) { timeMarker = new String[1]; timeMarker[0] = CommentRangeForm.shutdownCommentString; } Histogram[] histogram = new Histogram[timeMarker.Length]; Console.Write("Surviving objects for {0} allocated between {1} ({2} secs) and {3} ({4} secs) at", logFileName, startMarker, log.TickIndexToTime(startTickIndex), endMarker, log.TickIndexToTime(endTickIndex)); string separator = ""; for (int i = 0; i < timeMarker.Length; i++) { if (timeMarker[i] == null) timeMarker[i] = CommentRangeForm.shutdownCommentString; histogram[i] = GetSurvivorHistogram(log, entireLogResult, startTickIndex, endTickIndex, timeMarker[i]); int timeTickIndex = FindMarkerTickIndex(timeMarker[i], log); Console.Write("{0} {1} ({2} secs) ", separator, timeMarker[i], log.TickIndexToTime(timeTickIndex)); separator = ","; } Console.WriteLine(); WriteReport(histogram, timeMarker); }
private Histogram GetFinalHeapHistogram() { Histogram histogram = new Histogram(log); LiveObjectTable.LiveObject o; for (logResult.liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue && o.id + o.size >= o.id; logResult.liveObjectTable.GetNextObject(o.id + o.size, ulong.MaxValue, out o)) { histogram.AddObject(o.typeSizeStacktraceIndex, 1); } return histogram; }
private static void WriteReport(Histogram aHistogram, Histogram bHistogram) { DiffTypeDescriptor[] typeIndexToDiffTypeDescriptor = new DiffTypeDescriptor[aHistogram.readNewLog.typeName.Length]; FillHistogramIntoDiffTypeDescriptor(aHistogram, typeIndexToDiffTypeDescriptor); for (int i = 0; i < typeIndexToDiffTypeDescriptor.Length; i++) { DiffTypeDescriptor td = typeIndexToDiffTypeDescriptor[i]; if (td != null) { td.aSize = td.bSize; td.diffSize = - td.bSize; td.aCount = td.bCount; td.diffCount = - td.bCount; td.bSize = 0; td.bCount = 0; } } FillHistogramIntoDiffTypeDescriptor(bHistogram, typeIndexToDiffTypeDescriptor); ArrayList al = new ArrayList(); DiffTypeDescriptor totalTd = new DiffTypeDescriptor(0); for (int i = 0; i < typeIndexToDiffTypeDescriptor.Length; i++) { DiffTypeDescriptor td = typeIndexToDiffTypeDescriptor[i]; if (td != null) { al.Add(td); totalTd.aCount += td.aCount; totalTd.aSize += td.aSize; totalTd.diffCount += td.diffCount; totalTd.diffSize += td.diffSize; totalTd.bCount += td.bCount; totalTd.bSize += td.bSize; } } al.Sort(); Console.WriteLine("Start size,Start #instances,End size,End #instances,Diff size,Diff#instances,Typename"); Console.WriteLine("{0},{1},{2},{3},{4},{5},{6}", totalTd.aSize, totalTd.aCount, totalTd.bSize, totalTd.bCount, totalTd.diffSize, totalTd.diffCount, "Grand total"); foreach (DiffTypeDescriptor td in al) { Console.WriteLine("{0},{1},{2},{3},{4},{5},{6}", td.aSize, td.aCount, td.bSize, td.bCount, td.diffSize, td.diffCount, aHistogram.readNewLog.typeName[td.typeIndex]); } }
private string CalculateTotalSize(Histogram histogram) { double totalSize = 0.0; for (int i = 0; i < histogram.typeSizeStacktraceToCount.Length; i++) { int count = histogram.typeSizeStacktraceToCount[i]; if (count > 0) { int[] stacktrace = histogram.readNewLog.stacktraceTable.IndexToStacktrace(i); int size = stacktrace[1]; totalSize += (ulong)size*(ulong)count; } } return FormatNumber(totalSize); }
internal static void HeapDumpReport(string logFileName, string startMarker, string endMarker) { ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); Histogram[] heapDumpHistograms = entireLogResult.heapDumpHistograms; string[] timeMarkers = new String[heapDumpHistograms.Length]; if (startMarker != null || endMarker != null) { int startTickIndex = 0; int endTickIndex = entireLogResult.sampleObjectTable.lastTickIndex; if (startMarker != null) startTickIndex = FindMarkerTickIndex(startMarker, log); if (endMarker != null) endTickIndex = FindMarkerTickIndex(endMarker, log); int startIndex = 0; int endIndex = 0; for (int i = 0; i < log.heapDumpEventList.count; i++) { if (log.heapDumpEventList.eventTickIndex[i] < startTickIndex) startIndex = i + 1; if (log.heapDumpEventList.eventTickIndex[i] < endTickIndex) endIndex = i + 1; } if (endMarker == null) { Console.WriteLine("Heap dump for {0} after {1}", logFileName, startMarker); if (startIndex < log.heapDumpEventList.count) endIndex = startIndex + 1; else endIndex = startIndex; } else { Console.WriteLine("Heap dump for {0} between {1} and {2}", logFileName, startMarker, endMarker); } if (startIndex < endIndex) { heapDumpHistograms = new Histogram[endIndex - startIndex]; for (int i = startIndex; i < endIndex; i++) { heapDumpHistograms[i - startIndex] = entireLogResult.heapDumpHistograms[i]; } timeMarkers = new string[endIndex - startIndex]; } else { heapDumpHistograms = new Histogram[0]; timeMarkers = new string[0]; } } else { Console.WriteLine("Heap dumps for {0}", logFileName); } for (int i = 0; i < timeMarkers.Length; i++) { timeMarkers[i] = string.Format("Heap dump #{0}", i); } if (heapDumpHistograms.Length > 0) WriteReport(heapDumpHistograms, timeMarkers); else Console.WriteLine("***** No heap dumps found *****"); }
private Histogram MakeHistogram(int allocatedAfterTickIndex, int allocatedBeforeTickIndex) { // Build a histogram of types, sizes, allocation stacks from the object graph, // using only the objects whose vertices are selected // First of all, limit the interval to the one of the underlying graph if (allocatedAfterTickIndex < graph.allocatedAfterTickIndex) allocatedAfterTickIndex = graph.allocatedAfterTickIndex; if (allocatedBeforeTickIndex > graph.allocatedBeforeTickIndex) allocatedBeforeTickIndex = graph.allocatedBeforeTickIndex; Graph originalGraph = GetOriginalGraph(); ObjectGraph objectGraph = GetObjectGraph(); Histogram histogram = new Histogram(objectGraph.readNewLog); bool anyVertexSelected = SelectedVertexCount() != 0; foreach (KeyValuePair<ulong, ObjectGraph.GcObject> keyValuePair in objectGraph.idToObject) { ulong id = keyValuePair.Key; ObjectGraph.GcObject gcObject = keyValuePair.Value; if (gcObject.TypeSizeStackTraceId > 0 && gcObject.AllocTickIndex > allocatedAfterTickIndex && gcObject.AllocTickIndex < allocatedBeforeTickIndex && gcObject.InterestLevel != InterestLevel.Ignore) { if (anyVertexSelected || originalGraph != graph) { gcObject.vertex = null; Vertex v = objectGraph.FindVertex(id, gcObject, originalGraph, ObjectGraph.BuildTypeGraphOptions.LumpBySignature); if (originalGraph != graph) { v = graph.FindVertex(v.name, v.signature, v.moduleName); if (v == null) continue; } if (anyVertexSelected && !v.selected) continue; } histogram.AddObject(gcObject.TypeSizeStackTraceId, 1); } } return histogram; }
private static void WriteReport(Histogram[] histogram, string[] timeMarker) { TypeDescriptor[] typeIndexToTypeDescriptor = new TypeDescriptor[histogram[0].readNewLog.typeName.Length]; int[] totalSize = new int[histogram.Length]; int[] totalCount = new int[histogram.Length]; for (int h = 0; h < histogram.Length; h++) { int[] typeSizeStacktraceToCount = histogram[h].typeSizeStacktraceToCount; for (int i = 0; i < typeSizeStacktraceToCount.Length; i++) { int count = typeSizeStacktraceToCount[i]; if (count == 0) continue; int[] stacktrace = histogram[h].readNewLog.stacktraceTable.IndexToStacktrace(i); int typeIndex = stacktrace[0]; int size = stacktrace[1]; if (typeIndexToTypeDescriptor[typeIndex] == null) typeIndexToTypeDescriptor[typeIndex] = new TypeDescriptor(typeIndex, histogram.Length); typeIndexToTypeDescriptor[typeIndex].size[h] += size*count; typeIndexToTypeDescriptor[typeIndex].count[h] += count; totalSize[h] += size*count; totalCount[h] += count; } } ArrayList al = new ArrayList(); for (int i = 0; i < typeIndexToTypeDescriptor.Length; i++) { if (typeIndexToTypeDescriptor[i] == null) continue; al.Add(typeIndexToTypeDescriptor[i]); } al.Sort(); Console.Write("Typename"); for (int h = 0; h < histogram.Length; h++) Console.Write(",Size({0}),#Instances({1})", timeMarker[h], timeMarker[h]); Console.WriteLine(); Console.Write("Grand total"); for (int h = 0; h < histogram.Length; h++) Console.Write(",{0},{1}", totalSize[h], totalCount[h]); Console.WriteLine(); foreach (TypeDescriptor td in al) { Console.Write("{0}", histogram[0].readNewLog.typeName[td.typeIndex]); for (int h = 0; h < histogram.Length; h++) Console.Write(",{0},{1}", td.size[h], td.count[h]); Console.WriteLine(); } }
private void showWhoAllocatedMenuItem_Click(object sender, System.EventArgs e) { Histogram selectedHistogram; string title; TypeDesc selectedType = FindSelectedType(); double minAge = 0; double maxAge = double.PositiveInfinity; foreach (Bucket b in bucketTable) { if (b.selected) { minAge = b.minAge; maxAge = b.maxAge; } } title = "Allocation Graph for objects"; if (selectedType != null) title = string.Format("Allocation Graph for {0} objects", selectedType.typeName); if (minAge > 0.0) title += string.Format(" of age between {0} and {1} seconds", FormatTime(minAge), FormatTime(maxAge)); selectedHistogram = new Histogram(liveObjectTable.readNewLog); LiveObjectTable.LiveObject o; double nowTime = liveObjectTable.readNewLog.TickIndexToTime(liveObjectTable.lastTickIndex); for (liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue; liveObjectTable.GetNextObject(o.id + o.size, uint.MaxValue, out o)) { double age = nowTime - liveObjectTable.readNewLog.TickIndexToTime(o.allocTickIndex); if (minAge <= age && age < maxAge) { TypeDesc t = (TypeDesc)typeIndexToTypeDesc[o.typeIndex]; if (selectedType == null || t == selectedType) { selectedHistogram.AddObject(o.typeSizeStacktraceIndex, 1); } } } Graph graph = selectedHistogram.BuildAllocationGraph(new FilterForm()); GraphViewForm graphViewForm = new GraphViewForm(graph, title); graphViewForm.Visible = true; }
private void showHistogramMenuItem_Click(object sender, System.EventArgs e) { TypeDesc selectedType = FindSelectedType(); // Create a new histogram and add all the objects in the selected address range // whose type matches the selected type (if any). ReadNewLog log = liveObjectTable.readNewLog; Histogram histogram = new Histogram(log); ulong low = selectedLowAddr; ulong high = low == 0 ? ulong.MaxValue : selectedHighAddr; LiveObjectTable.LiveObject o; for (liveObjectTable.GetNextObject(low, high, out o); o.id < high; liveObjectTable.GetNextObject(o.id + o.size, high, out o)) { if (selectedType == null || selectedType.typeIndex == o.typeIndex) histogram.AddObject(o.typeSizeStacktraceIndex, 1); } string title = "Histogram by Size for live " + ComputeObjectsDescription(selectedType, selectedLowAddr, selectedHighAddr); HistogramViewForm histogramViewForm = new HistogramViewForm(histogram, title); histogramViewForm.Show(); }
/// <summary> /// Sonal: Function to generate and print Leak Report for the dump file. /// </summary> /// <param name="logFileName">dump file name</param> /// <param name="startMarker">int {0,NumHeapDumps}</param> /// <param name="endMarker">int {0,NumHeapDumps}</param> internal static void LeakReport(string logFileName, string startMarker, string endMarker) { if (startMarker == null) { startMarker = "1"; } if (endMarker == null) { endMarker = "2"; } int startIndex; int endIndex; try { startIndex = int.Parse(startMarker); endIndex = int.Parse(endMarker); } catch { throw new ArgumentException("Markers have to be positive integral values"); } startIndex--; endIndex--; if ((startIndex < 0) || (endIndex < 0)) { throw new ArgumentException("Markers can not be negative"); } var log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult, endIndex + 1); if (entireLogResult.requestedObjectGraph == null) { throw new ArgumentException("Invalid EndIndex"); } Histogram[] heapDumpHistograms = entireLogResult.heapDumpHistograms; string[] timeMarkers; if (startIndex < endIndex) { heapDumpHistograms = new Histogram[endIndex - startIndex + 1]; for (int i = startIndex; i <= endIndex; i++) { heapDumpHistograms[i - startIndex] = entireLogResult.heapDumpHistograms[i]; } timeMarkers = new string[endIndex - startIndex + 1]; } else { heapDumpHistograms = new Histogram[0]; timeMarkers = new string[0]; } for (int i = 0; i < timeMarkers.Length; i++) { timeMarkers[i] = string.Format("Heap dump #{0}", i + 1); } if (heapDumpHistograms.Length > 0) { WriteDiffReport(heapDumpHistograms, timeMarkers, entireLogResult); } else { Console.WriteLine("***** No heap dumps found *****"); } }