如何使用C#计算内存的私有工作集?我有兴趣制作与taskmgr.exe
大致相同的数字。
我正在使用Process
命名空间并使用WorkingSet64
和PrivateMemorySize64
等方法/数据,但这些数字有时会减少100MB或更多。
答案 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
会提供您需要的数据吗?