Dodgy .NET memory measurements using counters

There are a few profilers around that can measure CLR memory usage: Microsoft’s free CLR Profiler 2.0, JetBrains’ dotTrace, Redgate’s ANTS Profiler etc. However these don’t seem to help me much when I’m trying to get some data about specific allocations (say, plotting the size of a list with varying numbers of objects). This could just be my inexperience with the tools, but I think it is more to do with the complexities of memory management for managed code.

I’ve also been playing around with taking measurements by programatically accessing the relevant counters, like the Private Bytes counter in the Process category, in the effort to take a number of snapshots before and after some simple allocations and plug them into a spreadsheet.

  privateBytesCounter = new PerformanceCounter("Process", "Private Bytes", name, true);
  var currentMemoryInKB = privateBytesCounter.NextValue()/1024.0;

The name is the relevant instance that appears within perfmon. You need to watch out for invalid characters, but with some care you can derive this value from AppDomain.CurrentDomain.FriendlyName (you might need to strip off the ".exe" extension in addition to getting rid of any funny characters).

My aim was to work out the size of some specific objects, but I haven’t had too much success with this approach as it’s giving me some funny values. A couple of gotchas: You have to watch the timing of the calls getting counter data (don’t sample too fast), and if you are measuring a single allocation you can also change the results by forcing a garbage collection prior to measuring (GC.Collect()).

I think it’s time for me to invest in a good CLR book and get better acquainted with .NET’s memory model. :)