Skip to content

Commit

Permalink
Support new GC events
Browse files Browse the repository at this point in the history
  • Loading branch information
cshung committed Dec 16, 2022
1 parent 92c6ec0 commit 2f2d465
Show file tree
Hide file tree
Showing 17 changed files with 701 additions and 129 deletions.
4 changes: 2 additions & 2 deletions src/EtwHeapDump/DotNetHeapDumpGraphReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ internal void SetupCallbacks(MemoryGraph memoryGraph, TraceEventDispatcher sourc
}
};

source.Clr.GCGenAwareStart += delegate (GenAwareBeginTraceData data)
source.Clr.GCGenAwareBegin += delegate (GenAwareTemplateTraceData data)
{
m_seenStart = true;
m_ignoreEvents = false;
Expand Down Expand Up @@ -266,7 +266,7 @@ internal void SetupCallbacks(MemoryGraph memoryGraph, TraceEventDispatcher sourc
}
};

source.Clr.GCGenAwareEnd += delegate (GenAwareEndTraceData data)
source.Clr.GCGenAwareEnd += delegate (GenAwareTemplateTraceData data)
{
m_ignoreEvents = true;
if (m_nodeBlocks.Count == 0 && m_typeBlocks.Count == 0 && m_edgeBlocks.Count == 0)
Expand Down
39 changes: 39 additions & 0 deletions src/PerfView/GcStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,16 @@ public static void ToXml(TextWriter writer, TraceProcess stats, TraceLoadedDotNe
writer.Write("{0}<GCProcess", indent);
writer.Write(" Process={0}", StringUtilities.QuotePadLeft(stats.Name, 10));
writer.Write(" ProcessID={0}", StringUtilities.QuotePadLeft(stats.ProcessID.ToString(), 5));
if (runtime.GC.GCSettings != null)
{
writer.Write(" HardLimit=\"{0}\"", runtime.GC.GCSettings.HardLimit);
writer.Write(" LOHThreshold=\"{0}\"", runtime.GC.GCSettings.LOHThreshold);
writer.Write(" PhysicalMemoryConfig=\"{0}\"", runtime.GC.GCSettings.PhysicalMemoryConfig);
writer.Write(" Gen0MinBudgetConfig=\"{0}\"", runtime.GC.GCSettings.Gen0MinBudgetConfig);
writer.Write(" Gen0MaxBudgetConfig=\"{0}\"", runtime.GC.GCSettings.Gen0MaxBudgetConfig);
writer.Write(" HighMemPercentConfig=\"{0}\"", runtime.GC.GCSettings.HighMemPercentConfig);
writer.Write(" BitSettings=\"{0}\"", runtime.GC.GCSettings.BitSettings);
}
if (stats.CPUMSec != 0)
{
writer.Write(" ProcessCpuTimeMsec={0}", StringUtilities.QuotePadLeft(stats.CPUMSec.ToString("f0"), 5));
Expand Down Expand Up @@ -536,6 +546,15 @@ public static void ToXmlAttribs(TextWriter writer, TraceProcess stats, TraceLoad
}
}
}
if (gc.LOHCompactValues.Count > 0)
{
GCLOHCompactValues lohCompactValues = gc.LOHCompactValues[HeapNum];
writer.Write(" LohTimePlan =\"{0:n3}\" ", lohCompactValues.TimePlan);
writer.Write(" LohTimeCompact =\"{0:n3}\" ", lohCompactValues.TimeCompact);
writer.Write(" LohTimeRelocate =\"{0:n3}\" ", lohCompactValues.TimeRelocate);
writer.Write(" LohTotalRefs =\"{0}\" ", lohCompactValues.TotalRefs);
writer.Write(" LohZeroRefs =\"{0}\" ", lohCompactValues.ZeroRefs);
}
}
else
{
Expand All @@ -556,6 +575,26 @@ public static void ToXmlAttribs(TextWriter writer, TraceProcess stats, TraceLoad
}
writer.WriteLine(" </PerHeapHistories>");
}
if (gc.LargestFreeListItemsBuckets.Count > 0)
{
writer.WriteLine(" <LargestFreeListItemsBuckets>");
for (int i = 0; i < gc.LargestFreeListItemsBuckets.Count; i++)
{
GCFitBucketInfoValues bucket = gc.LargestFreeListItemsBuckets[i];
writer.WriteLine(" <Bucket Index=\"{0}\" Count=\"{1}\" Size=\"{2}\" />", bucket.Index, bucket.Count, bucket.Size);
}
writer.WriteLine(" </LargestFreeListItemsBuckets>");
}
if (gc.PlugsInCondemnedBuckets.Count > 0)
{
writer.WriteLine(" <PlugsInCondemnedBuckets>");
for (int i = 0; i < gc.PlugsInCondemnedBuckets.Count; i++)
{
GCFitBucketInfoValues bucket = gc.PlugsInCondemnedBuckets[i];
writer.WriteLine(" <Bucket Index=\"{0}\" Count=\"{1}\" Size=\"{2}\" />", bucket.Index, bucket.Count, bucket.Size);
}
writer.WriteLine(" </PlugsInCondemnedBuckets>");
}
writer.WriteLine(" </GCEvent>");
}

Expand Down
2 changes: 1 addition & 1 deletion src/PerfView/PerfViewData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3828,7 +3828,7 @@ public override void Open(Window parentWindow, StatusBar worker, Action doAfter)
// For .NET, we are looking for a Gen 2 GC Start that is induced that has GCBulkNodes after it.
var lastGCStartsRelMSec = new Dictionary<int, double>();

source.Clr.GCGenAwareStart += delegate (Microsoft.Diagnostics.Tracing.Parsers.Clr.GenAwareBeginTraceData data)
source.Clr.GCGenAwareBegin += delegate (Microsoft.Diagnostics.Tracing.Parsers.Clr.GenAwareTemplateTraceData data)
{
lastGCStartsRelMSec[data.ProcessID] = data.TimeStampRelativeMSec;
};
Expand Down
92 changes: 92 additions & 0 deletions src/TraceEvent/Computers/TraceManagedProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,44 @@ internal static void SetupCallbacks(TraceEventDispatcher source)
}
};

source.Clr.GCLOHCompact += delegate (GCLOHCompactTraceData data)
{
var stats = currentManagedProcess(data);
TraceGC _gc = TraceGarbageCollector.GetCurrentGC(stats);
if (_gc != null)
{
for (int i = 0; i < data.Count; i++)
{
_gc.LOHCompactValues.Add(data.Values(i));
}
}
};

source.Clr.GCFitBucketInfo += delegate (GCFitBucketInfoTraceData data)
{
BucketKind bucketKind = data.BucketKind;
var stats = currentManagedProcess(data);
TraceGC _gc = TraceGarbageCollector.GetCurrentGC(stats);
if (_gc != null)
{
for (int i = 0; i < data.Count; i++)
{
if (bucketKind == BucketKind.LargestFreeListItems)
{
_gc.LargestFreeListItemsBuckets.Add(data.Values(i));
}
else if (bucketKind == BucketKind.PlugsInCondemned)
{
_gc.PlugsInCondemnedBuckets.Add(data.Values(i));
}
else
{
Debug.Assert(false);
}
}
}
};

clrPrivate.GCPinPlugAtGCTime += delegate (PinPlugAtGCTimeTraceData data)
{
var stats = currentManagedProcess(data);
Expand Down Expand Up @@ -1212,6 +1250,11 @@ internal static void SetupCallbacks(TraceEventDispatcher source)
1;
};

clrRundownParser.GCSettingsRundown += delegate (GCSettingsRundownTraceData data)
{
var stats = currentManagedProcess(data);
stats.GC.m_gcSettings = new GCSettings(data.HardLimit, data.LOHThreshold, data.PhysicalMemoryConfig, data.Gen0MinBudgetConfig, data.Gen0MaxBudgetConfig, data.HighMemPercentConfig, data.BitSettings);
};
}

//
Expand Down Expand Up @@ -1505,6 +1548,7 @@ public class TraceGarbageCollector
/// Process view of GC statistics
/// </summary>
public GCStats Stats() { Calculate(); return m_stats; }

/// <summary>
/// Process view of GC generational statistics
/// </summary>
Expand All @@ -1515,6 +1559,11 @@ public class TraceGarbageCollector
/// </summary>
public List<TraceGC> GCs { get { return m_gcs; } }

/// <summary>
/// Settings for the GC
/// </summary>
public GCSettings GCSettings { get { return m_gcSettings; } }

#region private
internal static TraceGC GetCurrentGC(TraceLoadedDotNetRuntime proc)
{
Expand All @@ -1539,6 +1588,7 @@ internal static TraceGC GetCurrentGC(TraceLoadedDotNetRuntime proc)
private int m_prvcount = 0;
private int m_prvCompleted = 0;
internal double NextRelativeTimeStampMsec;
internal GCSettings m_gcSettings;

private void Calculate()
{
Expand Down Expand Up @@ -1753,6 +1803,36 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

namespace Microsoft.Diagnostics.Tracing.Analysis.GC
{
public class GCSettings
{
public long HardLimit { get { return m_HardLimit; } }
public long LOHThreshold { get { return m_LOHThreshold; } }
public long PhysicalMemoryConfig { get { return m_PhysicalMemoryConfig; } }
public long Gen0MinBudgetConfig { get { return m_Gen0MinBudgetConfig; } }
public long Gen0MaxBudgetConfig { get { return m_Gen0MaxBudgetConfig; } }
public int HighMemPercentConfig { get { return m_HighMemPercentConfig; } }
public int BitSettings { get { return m_BitSettings; } }

public GCSettings(long HardLimit, long LOHThreshold, long PhysicalMemoryConfig, long Gen0MinBudgetConfig, long Gen0MaxBudgetConfig, int HighMemPercentConfig, int BitSettings)
{
m_HardLimit = HardLimit;
m_LOHThreshold = LOHThreshold;
m_PhysicalMemoryConfig = PhysicalMemoryConfig;
m_Gen0MinBudgetConfig = Gen0MinBudgetConfig;
m_Gen0MaxBudgetConfig = Gen0MaxBudgetConfig;
m_HighMemPercentConfig = HighMemPercentConfig;
m_BitSettings = BitSettings;
}

private long m_HardLimit;
private long m_LOHThreshold;
private long m_PhysicalMemoryConfig;
private long m_Gen0MinBudgetConfig;
private long m_Gen0MaxBudgetConfig;
private int m_HighMemPercentConfig;
private int m_BitSettings;
}

/// <summary>
///
/// </summary>
Expand Down Expand Up @@ -2459,6 +2539,18 @@ public void GetCondemnedReasons(Dictionary<CondemnedReasonGroup, int> ReasonsInf
/// This represents the percentage time spent paused for this GC since the last GC completed.
/// </summary>
public double PauseTimePercentageSinceLastGC;
/// <summary>
/// LOH Compaction Data
/// </summary>
public List<GCLOHCompactValues> LOHCompactValues = new List<GCLOHCompactValues>();
/// <summary>
/// TODO, Andrew, Comment
/// </summary>
public List<GCFitBucketInfoValues> LargestFreeListItemsBuckets = new List<GCFitBucketInfoValues>();
/// <summary>
/// TODO, Andrew, Comment
/// </summary>
public List<GCFitBucketInfoValues> PlugsInCondemnedBuckets = new List<GCFitBucketInfoValues>();

#region private
internal void OnEnd(TraceGarbageCollector details)
Expand Down
Loading

0 comments on commit 2f2d465

Please sign in to comment.