C#을 사용하여 개인 작업 집합을 계산하는 방법은 무엇입니까? 나는 taskmgr.exe
와 대략 같은 숫자를 생산하는데 관심이 있습니다.개인 작업 집합 (메모리)을 계산하는 방법은 무엇입니까?
나는 프로세스 네임 스페이스를 사용하고 WorkingSet64
및 PrivateMemorySize64
과 같은 방법/데이터를 사용하고 있지만이 수치는 100MB 이상 떨어져 있습니다.
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을 위해 경쟁 할 것이다.
GC.GetTotalMemory
이 필요한 데이터를 제공합니까?
여러 사용자가있을 수있는 프로세스에 대해 개인 작업 세트를 얻으려면 다음 단계를 수행해야합니다. 나는 GetNameToUseForMemory
에서 적절한 프로세스 이름을 얻는 CurrentMemoryUsage
을 호출한다. 내가 할 수있는 곳에서 결과를 필터링하는 경우에도이 루프가 느린 것으로 나타났습니다. 따라서 이름을 캐싱하기 위해 사전을 사용하는 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이 "다시 키잉"될 수 있으므로 값 캐싱이 작동하지 않습니다. http://blogs.technet.com/b/askperf/archive/2010/03/30/perfmon -identifying-processes-by-pid-instance-.aspx 대신 – Andre
@Andre 맞습니다! 텍사스 –
"숫자가 실제로 의미가 크지 않다"는 것을 어떻게 의미합니까? 이 수치는 프로세스가 다른 프로세스와 공유 할 수없는 메모리의 양을 나타내지는 않습니까? 저는 프로세스 "악의적 인"프로세스를 죽일 서비스를 만드는 것에 관심이 있습니다. "악의적 인"프로세스는 x MB 이상의 메모리를 사용하는 프로세스로 정의됩니다. 제가 사용하는 그림이 실제로 의미가 크지 않다면 서비스를 작성하는 것을 싫어할 것입니다. 무엇을 제안하겠습니까? – sholsapp
아니, 숫자가 의미하는 것이 아닙니다. 다른 프로세스가 공유 할 수없는 프로세스에 의해 사용 된 가상 메모리의 양인 "Private Bytes"를 찾고 있습니다. –
모든 것이 정확하다고 말하면서, 단지 'ProcessName'을 사용하여 일치하는 카운터 인스턴스를 조회하는 것만으로는 충분하지 않다고 덧붙이고 싶습니다. 동일한 프로세스 (예 : svchost.exe)가 여러 개있는 경우 카운터 이름은 "svchost # 1", "svchost # 2"등이됩니다. 또한 "ID 프로세스"카운터를 통해 일치해야합니다 프로세스 카테고리의'Process.ID'. –