How do I calculate the private working set of memory using C#? I'm interested in producing roughly the same figures as taskmgr.exe
.
I'm using the Process
namespace and using methods/data like WorkingSet64
and PrivateMemorySize64
, but these figures are off by 100MB or more at times.
This is a highly variable number, you cannot calculate it. The Windows memory manager constantly swaps pages in and out of RAM. TaskMgr.exe gets it from a performance counter. You can get the same number like this:
using System;
using System.Diagnostics;
class Program {
static void Main(string[] args) {
string prcName = Process.GetCurrentProcess().ProcessName;
var counter = new PerformanceCounter("Process", "Working Set - Private", prcName);
Console.WriteLine("{0}K", counter.RawValue / 1024);
Console.ReadLine();
}
}
Do beware that the number really doesn't mean much, it will drop when other processes get started and compete for RAM.
For future users, here is what I had to do to make sure to get the Private Working Set for processes that might have multiple instances. I call CurrentMemoryUsage
, which gets the appropriate process name from GetNameToUseForMemory
. I found this loop to be slow, even with filtering down the results where I could. So, that is why you see GetNameToUseForMemory
using a dictionary for caching the name.
private static long CurrentMemoryUsage(Process proc)
{
long currentMemoryUsage;
var nameToUseForMemory = GetNameToUseForMemory(proc);
using (var procPerfCounter = new PerformanceCounter("Process", "Working Set - Private", nameToUseForMemory))
{
//KB is standard
currentMemoryUsage = procPerfCounter.RawValue/1024;
}
return currentMemoryUsage;
}
private static string GetNameToUseForMemory(Process proc)
{
if (processId2MemoryProcessName.ContainsKey(proc.Id))
return processId2MemoryProcessName[proc.Id];
var nameToUseForMemory = String.Empty;
var category = new PerformanceCounterCategory("Process");
var instanceNames = category.GetInstanceNames().Where(x => x.Contains(proc.ProcessName));
foreach (var instanceName in instanceNames)
{
using (var performanceCounter = new PerformanceCounter("Process", "ID Process", instanceName, true))
{
if (performanceCounter.RawValue != proc.Id)
continue;
nameToUseForMemory = instanceName;
break;
}
}
if(!processId2MemoryProcessName.ContainsKey(proc.Id))
processId2MemoryProcessName.Add(proc.Id, nameToUseForMemory);
return nameToUseForMemory;
}
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