I have the following code to launch and monitor a process:
Process process = new Process();
process.StartInfo.FileName = "foo.exe";
long maxMemoryUsage = 0;
process.Start()
while(!process.HasExited)
{
maxMemoryUsage = Math.Max(maxMemoryUsage, process.PrivateMemorySize64);
}
After using this code to run a large application that, according to the task manager used 328 MB at its peak (Memory "Private Working Set"). The value of maxMemoryUsage, and the value of process.PeakPagedMemorySize64 is 364544. According to MSDN this value should be interpreted as bytes, meaning it is a little over 300KB, a factor thousand away from the expected value. The other process.Peak...Memory properties also report extremely low values (all under a megabyte, except for PeakVirtualMemorySize64 which is 4MB which I think is the minimum value for this field).
I've tried launching different applications (C# and C++ based of which I have the source code) which I know to use very little or a lot of memory and the memory values where always very close to the values seen with this process. Apparently I'm doing something completely wrong.
So my question is: How can I measure the maximum memory usage of a process which I spawned from my C# application. (Note that I don't need to have the value ealtime as long as I know its value after the program exited, I also don't need it super precise as I don't care if it was 27.04MB or 30MB, but I do care if it was 30MB or 100MB).
Edit: here is a full reproducable test case
class Program
{
static void Main(string[] args)
{
Process process = new Process();
process.StartInfo.FileName = @"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe";
long maxMemoryUsage = 0;
process.Start();
while(!process.HasExited)
{
maxMemoryUsage = Math.Max(maxMemoryUsage, process.PagedMemorySize64);
}
Console.Out.WriteLine("Memory used: " + (maxMemoryUsage / 1024.0) / 1024.0 + "MB");
Console.ReadLine();
}
}
According to the task manager Visual Studio uses 103MB. After closing Visual Studio the program reports 0.3984375MB.
Process class is heavily cached. You'll get only cached result, no matter how many times you read some property unless you throw a call to Refresh method. You need to call Process.Refresh to get the non cached result.
To quote from msdn
When a Process component is associated with a process resource, the property values of the Process are immediately populated according to the status of the associated process. If the information about the associated process subsequently changes, those changes are not reflected in the Process component's cached values. The Process component is a snapshot of the process resource at the time they are associated. To view the current values for the associated process, call the Refresh method.
So, your code will become:
while(!process.HasExited)
{
process.Refresh();
maxMemoryUsage = Math.Max(maxMemoryUsage, process.PrivateMemorySize64);
}
Also you may consider looking at process.PeakXXX properties, that will help you I suppose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With