Skip to content

Instantly share code, notes, and snippets.

@stdray
Created August 30, 2017 18:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stdray/0105c4b75bb88229fbbe4c80cab55d2b to your computer and use it in GitHub Desktop.
Save stdray/0105c4b75bb88229fbbe4c80cab55d2b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ByteSizeLib;
using CommandLine;
using Microsoft.Diagnostics.Runtime;
namespace MemStat
{
internal class Program
{
static void Main(string[] args)
{
var result = Parser.Default.ParseArguments<Options>(args);
result.WithNotParsed(errors =>
{
foreach (var error in errors)
Console.WriteLine(error);
});
result.WithParsed(options =>
{
using (var target = DataTarget.AttachToProcess(options.Pid, 5000, AttachFlag.NonInvasive))
{
var runtimeInfo = target.ClrVersions.First();
var runtime = runtimeInfo.CreateRuntime();
if (!runtime.Heap.CanWalkHeap)
{
Console.WriteLine("Cannot walk the heap!");
return;
}
var typeInfo = new Dictionary<ClrType, InstancesInfo>();
var totalSize = 0ul;
foreach (var obj in runtime.Heap.EnumerateObjects())
{
totalSize += obj.Size;
if (typeInfo.TryGetValue(obj.Type, out var info))
{
info.Count++;
info.Size += obj.Size;
}
else
{
typeInfo.Add(obj.Type, new InstancesInfo
{
Count = 1,
Size = obj.Size
});
}
}
PrintToConsole(options, typeInfo, totalSize);
if(!string.IsNullOrEmpty(options.File))
PrintToFile(options, typeInfo, totalSize);
}
});
Console.WriteLine("Enter to exit...");
Console.ReadLine();
}
static void PrintToFile(Options options, Dictionary<ClrType, InstancesInfo> typeInfo, ulong totalSize)
{
using (var writer = new StreamWriter(options.File))
{
writer.WriteLine($"Total: {ByteSize.FromBytes(totalSize)}");
foreach (var kv in typeInfo.OrderByDescending(kv => kv.Value.Size))
{
writer.WriteLine($"{kv.Key.Name,-60}\t{kv.Value.Count}\t{ByteSize.FromBytes(kv.Value.Size)}");
}
}
}
static void PrintToConsole(Options options, Dictionary<ClrType, InstancesInfo> typeInfo, ulong totalSize)
{
Console.WriteLine("...");
foreach (var kv in typeInfo.OrderByDescending(kv => kv.Value.Size).Take(options.Number).Reverse())
{
Console.WriteLine($"{kv.Key.Name,-60}\t{kv.Value.Count}\t{ByteSize.FromBytes(kv.Value.Size)}");
}
Console.WriteLine($"Total: {ByteSize.FromBytes(totalSize)}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment