Skip to content

Instantly share code, notes, and snippets.

public class Cleaner<T, S>
where T : class
{
private const int DefaultCleanupPeriod = 1000;
private Action<S> _onCleanup;
private Action<Exception> _onError;
private readonly ReferenceQueue<T> _queue;
private readonly Thread _cleanerThread;
private readonly ManualResetEvent _exitEvent;
class Program
{
static void Main(string[] args)
{
InnerScope();
GC.Collect();
GC.WaitForPendingFinalizers();
public class ReferenceQueue<T>
where T : class
{
...
internal void Track(T value, PhantomReference<T> reference)
{
_table.Add(value, reference);
}
public interface IGcLog
{
void Start(string filename);
void Stop();
}
public abstract class GcLogBase : IGcLog
{
protected string Filename;
private StreamWriter _fileWriter;
public void Start(string filename)
{
if (string.IsNullOrEmpty(filename))
throw new ArgumentNullException(nameof(filename));
EtwGcLog gcLog = EtwGcLog.GetProcessGcLog(pid);
var filename = GetUniqueFilename(pid);
gcLog.Start(filename);
// in a simple Console application, wait for the user to press ENTER.
// in a more realistic case, keep track of the EtwLog instance and
// call Stop to end the processing of events when needed.
gcLog.Stop();
private static string GetUniqueFilename(int pid)
{
var now = DateTime.Now;
string filename = Path.Combine(Environment.CurrentDirectory,
$"{pid.ToString()}_{now.Year}{now.Month}{now.Day}_{now.Hour}{now.Minute}{now.Second}.csv"
);
return filename;
}
public static EtwGcLog GetProcessGcLog(int pid)
{
EtwGcLog gcLog = null;
try
{
var process = Process.GetProcessById(pid);
process.Dispose();
gcLog = new EtwGcLog(pid);
}
protected override void OnStart()
{
string sessionName = $"GcLogEtwSession_{_pid.ToString()}_{Guid.NewGuid().ToString()}";
Console.WriteLine($"Starting {sessionName}...\r\n");
_userSession = new TraceEventSession(sessionName, TraceEventSessionOptions.Create);
Task.Run(() =>
{
// only want to receive GC event
ClrEventsManager manager = new ClrEventsManager(_userSession, _pid, EventFilter.GC);
private void OnGarbageCollection(object sender, GarbageCollectionArgs e)
{
_line.Clear();
_line.AppendFormat("{0},", e.StartRelativeMSec.ToString());
_line.AppendFormat("{0},", e.Number.ToString());
_line.AppendFormat("{0},", e.Generation.ToString());
_line.AppendFormat("{0},", e.Type);
_line.AppendFormat("{0},", e.Reason);
_line.AppendFormat("{0},", e.IsCompacting.ToString());
_line.AppendFormat("{0},", e.SuspensionDuration.ToString());