views:

1013

answers:

5

I have a long running console app running through millions of iterations. I want to benchmark if memory usage increases linerally as the number of iterations increases.

What would be the best way to go about this?

I think I really only need to be concerned with Peak memory usage during a run right? I basically need to work out what is the max number of iterations I can run on this hardware given the memory on the Server.

I am going to setup a batch lot of runs and Log the results over different interation sizes and then graph the results to identify a memory usage trend which can then be extrapolated for any given hardware.

Looking for advice on the best way to implement this, what .net methods, classes to use or should I use external tools. This article http://www.itwriting.com/dotnetmem.php suggests I should profile my own app via code to factor out shared memory used by the .net runtime across other apps on the box.

Thanks

+3  A: 

Windows perfmon is great for this kind of stuff. You have counters for all the managed heaps and for private bytes, if you need to cross correlate with iteration counts you can publish your own perfmon counters from .Net.

Sam Saffron
+1  A: 

when you want to profile the mem usage of your apps, here is a piece of code you can use. First you have to declare an instance of the PerformanceCounter class

Assembly a = Assembly.GetExecutingAssembly();
_PerfCounter = new PerformanceCounter(".NET CLR Memory",
                                      "# Bytes in all Heaps",
                                      a.GetName().Name,
                                      true);

and each time you want to log the memory consumption you can call

_PerfCounter.NextValue()

Hope it was helpful

PierrOz
When I run this code above I get:Instance 'IRC' does not exist in the specified Category.IRC is my assembly name, what is happening here?
m3ntat
A: 

Maybe this tool can do everything you want.

Fernando
+2  A: 

There are several ways to do this:

Perfmon UI

You can use the Performance Montior control panel applet (in Administrative Tools) that comes with Windows to monitor your application. Have a look at the .Net CLR Memory category and the counters inside it. You can also limit the monitoring to just your process. This is probably the easiest as it requires no code changes.

Perfmon API

You can programmatically use performance counters from .Net. For this, you'll need to use the PerformanceCounter class. This is just an API to the same underlying information that the above UI presents.

Memory Profiler

You can use a memory profiler to profile you application whilst it is running. The two I have used with success are the ANTS Memory Profiler from RedGate and the .Net Memory Profiler from SciTech. Again, this requires no code changes, but may cost you money (although there are free trial versions). There is also the CLR Profiler (a howto can be found here).

Roll Your Own

You can get hold of some limited memory information from the Process class. Get hold of the current process using Process.GetCurrentProcess(), and then look at the properties of it, specifically the ones relating to memory (MinWorkingSet, MaxWorkingSet, PagedMemorySize64, PeakPagedMemorySize64, PeakVirtualMemorySize64, PeakWorkingSet64, PrivateMemorySize64, VirtualMemorySize64, WorkingSet64). This is probably the worst solution as you have to do everything yourself, including data collection and reporting.


If all you are wanting to do is to verify your application doesn't linearly increase its memory usage as your the number of iterations increases, I would recommend monitoring using the Performance Monitor UI in Windows. It will show you what you need with minimal effort on your part.

adrianbanks
Thanks Adrian, I am going to go with the "Roll Your Own" option. It suits my circumstance where I need to run one app which internally performs multiple runs with varying parameters (one being iteration size) and I need to profile each run independently not the whole console application.I am thinking I'll take snapshots of the program state before and after each run (and maybe during each run if necessary unless I can get the peak used? somehow for the run) and then calc max memory used. Which properties and methods would be best in this instance.Thanks
m3ntat
I would have thought that WorkingSet64 and PeakWorkingSet64 would be what you need to use. These give the current and peak memory used by the process.
adrianbanks
A: 

Better late than never, but in response to M3ntat's comment, you'll need to add ".vshost" onto the assembly name parameter if you're running from within Visual Studio, e.g.

a.GetName().Name + ".vshost"
Gareth