GcEventExtra GetGcEventExtra(int gc, bool create = true) { GcEventExtra data; if (!m_gcEventExtra.TryGetValue(gc, out data) && create) { data = new GcEventExtra(); m_gcEventExtra[gc] = data; } return(data); }
private void OnOpenInducedStacks(object sender, RoutedEventArgs e) { StackSourceBuilder builder = new StackSourceBuilder(m_traceLog); List <TraceGC> events = m_runtime.GC.GCs; for (int i = 0; i < events.Count; i++) { TraceGC ev = events[i]; if (ev.IsInduced()) { GcEventExtra extra = GetGcEventExtra(ev.Number, false); if (extra != null) { builder.AddSample(extra.GCStartThread, ev.PauseDurationMSec, ev.StartRelativeMSec, String.Format("StartGC({0}, {1}, G{2})", ev.Reason, ev.Type, ev.Generation), extra.GCStartIndex); } } } StackSource source = builder.Stacks; if (source.SampleIndexLimit == 0) { MessageBox.Show("No stacks found for induced GC", ".Net Heap Analyzer", MessageBoxButton.OK); } else { StackWindow stackWindow = null; m_dataFile.StackWindowTo(null, ref stackWindow, source, "Induced GC", FirstEventTime, LastEventTime); } }
internal void OnClrEvent(TraceEvent data) { TraceEventID eventID = data.ID; HeapEvents heapEvent = HeapEvents.Unknown; // TODO don't use IDs but use individual callbacks. const TraceEventID GCStartEventID = (TraceEventID)1; const TraceEventID GCStopEventID = (TraceEventID)2; const TraceEventID GCRestartEEStopEventID = (TraceEventID)3; const TraceEventID GCHeapStatsEventID = (TraceEventID)4; const TraceEventID GCCreateSegmentEventID = (TraceEventID)5; const TraceEventID GCFreeSegmentEventID = (TraceEventID)6; const TraceEventID GCRestartEEStartEventID = (TraceEventID)7; const TraceEventID GCSuspendEEStopEventID = (TraceEventID)8; const TraceEventID GCSuspendEEStartEventID = (TraceEventID)9; const TraceEventID GCAllocationTickEventID = (TraceEventID)10; const TraceEventID GCCreateConcurrentThreadEventID = (TraceEventID)11; const TraceEventID GCTerminateConcurrentThreadEventID = (TraceEventID)12; const TraceEventID GCFinalizersStopEventID = (TraceEventID)13; const TraceEventID GCFinalizersStartEventID = (TraceEventID)14; const TraceEventID ContentionStartEventID = (TraceEventID)81; const TraceEventID ContentionStopEventID = (TraceEventID)91; switch (eventID) { case GCStartEventID: { var mdata = data as Microsoft.Diagnostics.Tracing.Parsers.Clr.GCStartTraceData; if (mdata != null) { GcEventExtra extra = GetGcEventExtra(mdata.Count); extra.GCStartIndex = data.EventIndex; extra.GCStartThread = data.Thread(); } } heapEvent = HeapEvents.GCStart; break; case GCStopEventID: heapEvent = HeapEvents.GCEnd; break; case GCRestartEEStartEventID: heapEvent = HeapEvents.GCRestartEEBegin; break; case GCRestartEEStopEventID: heapEvent = HeapEvents.GCRestartEEEnd; break; case GCHeapStatsEventID: heapEvent = HeapEvents.GCHeapStats; break; case GCCreateSegmentEventID: heapEvent = HeapEvents.GCCreateSegment; break; case GCFreeSegmentEventID: heapEvent = HeapEvents.GCFreeSegment; break; case GCSuspendEEStartEventID: heapEvent = HeapEvents.GCSuspendEEBegin; break; case GCSuspendEEStopEventID: heapEvent = HeapEvents.GCSuspendEEEnd; break; case GCAllocationTickEventID: heapEvent = HeapEvents.GCAllocationTick; { GCAllocationTickTraceData mdata = data as GCAllocationTickTraceData; AllocationTick(mdata, mdata.AllocationKind == GCAllocationKind.Large, mdata.GetAllocAmount(ref seenBadAlloc) / OneMBD); } break; case GCCreateConcurrentThreadEventID: heapEvent = HeapEvents.GCCreateConcurrentThread; break; case GCTerminateConcurrentThreadEventID: heapEvent = HeapEvents.GCTerminateConcurrentThread; break; case GCFinalizersStartEventID: heapEvent = HeapEvents.GCFinalizersBegin; break; case GCFinalizersStopEventID: heapEvent = HeapEvents.GCFinalizersEnd; break; case ContentionStartEventID: heapEvent = HeapEvents.ContentionStart; break; case ContentionStopEventID: heapEvent = HeapEvents.ContentionStop; break; default: break; } if (heapEvent != HeapEvents.Unknown) { ThreadMemoryInfo thread = GetThread(data.ThreadID); thread.AddEvent(heapEvent, data.TimeStampRelativeMSec); } }