如何计算私有工作集(内存)?

Posted

技术标签:

【中文标题】如何计算私有工作集(内存)?【英文标题】:How to calculate private working set (memory)? 【发布时间】:2011-02-06 08:33:47 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

这是一个高度可变的数字,你无法计算它。 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("0K", counter.RawValue / 1024);
        Console.ReadLine();
    

请注意,这个数字实际上并没有多大意义,当其他进程启动并竞争 RAM 时,它会下降。

【讨论】:

你是什么意思,“这个数字真的没有多大意义”?这个数字不是代表进程使用了​​多少内存而不能与另一个进程共享吗?我有兴趣构建一个将杀死进程“滥用”进程的服务 - “滥用”被定义为使用超过 x 多 MB 内存的进程。如果我使用的数字真的没有多大意义,我会讨厌编写服务。你有什么建议? 不,这不是这个数字的意思。您正在寻找“Private Bytes”,即一个进程占用的、其他进程无法共享的虚拟内存量。 虽然说的都是正确的,但我想补充一点,仅使用ProcessName 查找匹配的计数器实例是不够的。如果您有多个相同的进程(例如 svchost.exe),那么计数器名称将是“svchost#1”、“svchost#2”等。您需要通过“ID 进程”计数器进行匹配,这也是一部分进程类别,Process.ID.【参考方案2】:

对于未来的用户,这是我必须做的,以确保为可能有多个实例的进程获取私有工作集。我调用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;

【讨论】:

请注意,缓存该值将不起作用,因为“旧”进程可能会关闭并且 instanceName 会“重新键入”blogs.technet.com/b/askperf/archive/2010/03/30/… 链接断开:在此处更新techcommunity.microsoft.com/t5/ask-the-performance-team/…

以上是关于如何计算私有工作集(内存)?的主要内容,如果未能解决你的问题,请参考以下文章

任务列表与任务管理器内存

决战圣地玛丽乔亚Day39 -----GC内存模型类加载

如何在 C# 中获取可用或使用的内存

内存的工作集、高峰工作集、工作集增量、专用工作集、提交大小、页面缓冲池、非页面缓冲池 的区别

dask 如何处理大于内存的数据集

如何在 python 2.7 32bit 中获取 64bit 进程的内存工作集?