【发布时间】:2019-05-01 22:42:09
【问题描述】:
我正在构建一个小型控制台应用程序,该应用程序会强制关闭使用一定内存量的进程,并且当 CPU 已经在使用其大量功率时,我正在努力让它正常工作。
每当我使用 PerformanceCounter 获取 Private Working Set 内存时,我很容易陷入以下异常:
发生了一个或多个错误
在我看来,如果我将 PerformanceCounter “附加”到一个进程,我就不能再简单地 .Kill() 它了。这当然是一个较慢的过程,即使是获取值也是如此。
当我使用任务管理器时,我可以清楚地看到一个进程的内存使用情况。如果我进入 Details 选项卡,我可以看到 memory 列实际上是“Private Working Set”值。
有没有办法以更优化、更快的方式获得此值?
这是我用来通过 PerformanceCounter 获取私有工作集的代码:
public static long GetPrivateWorkingSetMemoryOfProcess(Process process)
{
long process_size = 0;
String InstanceName = PerformanceCounterInstanceName(process);
var counter = new PerformanceCounter("Process", "Working Set - Private", InstanceName, true);
process_size = Convert.ToInt32(counter.NextValue()) / 1024;
return process_size;
}
由于 PerformanceCounter 使用进程名称作为参数,而不是 ID,因此我使用此函数来获取进程的正确进程名称:
public static string PerformanceCounterInstanceName(this Process process)
{
var matchesProcessId = new Func<string, bool>(instanceName =>
{
using (var pc = new PerformanceCounter("Process", "ID Process", instanceName, true))
{
if ((int)pc.RawValue == process.Id)
{
return true;
}
}
return false;
});
string processName = Path.GetFileNameWithoutExtension(process.ProcessName);
return new PerformanceCounterCategory("Process")
.GetInstanceNames()
.AsParallel()
.FirstOrDefault(instanceName => instanceName.StartsWith(processName)
&& matchesProcessId(instanceName));
}
这里是我将使用它来杀死具有一定内存使用量的进程的地方:
//get Process By ID
Process processToClose = Process.GetProcessById(Convert.ToInt32(processid));
long processesPrivateWorkingSetMemoryUsage = GetPrivateWorkingSetMemoryOfProcess(processToClose);
Console.WriteLine("Process '" + processid + "' uses " + processesPrivateWorkingSetMemoryUsage.ToString() + " memory.");
if (processesPrivateWorkingSetMemoryUsage <= 8000)
{
processToClose.Kill()
}
【问题讨论】:
-
“发生了一个或多个错误” - 这通常是 AggregateException,它本身并不是很有帮助。确保您检查(并相应地更新您的问题)InnerExceptions 属性以了解真正的问题。
-
还有一件事:“当 CPU 已经在使用大量功率时”......“这当然是一个较慢的过程,即使是获取值”你不认为这些是(自然)相关?
-
最佳解决方案可能是根本不执行任何操作,而是通过调用SetProcessWorkingSetSizeEx 让系统强制执行硬限制。根据您使用的系统,可能会有预先构建的解决方案(如Windows System Resource Manager)。
标签: c# windows winforms winapi