How to calculate private working set (memory)?

25,788

Solution 1

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.

Solution 2

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;
}
Share:
25,788
Admin
Author by

Admin

Updated on November 04, 2020

Comments

  • Admin
    Admin over 3 years

    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.