Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何计算专用工作集(内存)?_C#_Memory_Memory Management - Fatal编程技术网

C# 如何计算专用工作集(内存)?

C# 如何计算专用工作集(内存)?,c#,memory,memory-management,C#,Memory,Memory Management,如何使用C#计算内存的私有工作集?我对生成与taskmgr.exe大致相同的数字感兴趣 我正在使用进程名称空间,并使用诸如WorkingSet64和PrivateMemorySize64之类的方法/数据,但这些数字有时会减少100MB或更多。这是一个高度可变的数字,您无法计算它。Windows内存管理器不断地在RAM中交换页面。TaskMgr.exe从性能计数器获取它。您可以得到如下相同的号码: using System; using System.Diagnostics; class Pro

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


我正在使用
进程
名称空间,并使用诸如
WorkingSet64
PrivateMemorySize64
之类的方法/数据,但这些数字有时会减少100MB或更多。

这是一个高度可变的数字,您无法计算它。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时,它将下降。

对于未来的用户,我必须做以下几点来确保为可能有多个实例的进程获得私有工作集。我调用
currentmoryusage
,它从
getnametouseformory
获取适当的进程名称。我发现这个循环很慢,即使在我可以过滤结果的地方。因此,这就是为什么您会看到使用字典缓存名称的原因

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

你怎么说“这个数字真的没有多大意义”?这个数字不代表进程使用了多少不能与另一个进程共享的内存吗?我感兴趣的是构建一个能够杀死进程“滥用”进程的服务——“滥用”被定义为使用超过x多MB内存的进程。如果我使用的数字真的没有多大意义,我就不愿意写服务了。你有什么建议?不,这个数字不是这个意思。您正在查找“Private Bytes”,即一个进程占用的、其他进程无法共享的虚拟内存量。虽然所说的都是正确的,但我想补充的是,仅使用
ProcessName
查找匹配的计数器实例是不够的。如果您有多个进程具有相同的名称(例如svchost.exe),那么计数器名称将是“svchost#1”、“svchost#2”等。您需要通过“ID Process”计数器进行匹配,该计数器也是进程类别的一部分,并且
Process.ID
。请注意,缓存该值不会起作用,因为“较旧”进程可能会关闭,instanceName会丢失“重新设置关键帧”断开链接:此处更新