如何计算私人工作集(记忆)?

时间:2010-04-09 21:42:57

标签: c# memory memory-management

如何使用C#计算内存的私有工作集?我有兴趣制作与taskmgr.exe大致相同的数字。

我正在使用Process命名空间并使用WorkingSet64PrivateMemorySize64等方法/数据,但这些数字有时会减少100MB或更多。

3 个答案:

答案 0 :(得分:28)

这是一个高度可变的数字,你无法计算它。 Windows内存管理器不断地将页面交换进RAM。 TaskMgr.exe从性能计数器获取它。你可以得到这样的数字:

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();
    }
}

请注意,这个数字并不意味着什么,当其他进程开始并竞争RAM时,它会下降。

答案 1 :(得分:1)

对于未来的用户,我必须做的就是确保为可能有多个实例的进程获取私有工作集。我致电CurrentMemoryUsage,它从GetNameToUseForMemory获取相应的流程名称。我发现这个循环很慢,即使我尽可能地过滤掉结果。所以,这就是为什么你看到GetNameToUseForMemory使用字典来缓存名称。

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;
}

答案 2 :(得分:0)

也许GC.GetTotalMemory会提供您需要的数据吗?