【发布时间】:2012-04-07 08:28:35
【问题描述】:
我有一个 C# 应用程序,它使用 Process.Start() 启动另一个可执行文件。
这个调用在 99% 的情况下都能正常工作。但是,在应用程序运行了一段时间后,Process.Start() 将失败并显示错误消息:
Insufficient system resources exist to complete the requested service
最初我认为这一定是由于我的程序中的内存泄漏 - 我已经对其进行了相当广泛的分析,并且似乎没有泄漏 - 即使此消息失败,内存占用仍然是合理的。
在发生这样的故障后,如果我立即打印一些系统统计信息,我似乎有超过 600MB 的可用 RAM、足够的磁盘空间,并且 CPU 使用率实际上是 0%。
还有其他一些我没有想到的系统资源吗?我是否在 .NET VM 中遇到内存限制?
编辑2:
我在 SysInternals Process Explorer 中打开了应用程序,看起来我正在左右泄漏句柄:
Handles Used: 11,950,352 (!)
GDI Handles: 26
USER Handles: 22
这里奇怪的是,Win32 端的句柄看起来很合理,但不知何故,我的原始句柄数已经爆炸 waaaaay 失控了。有什么想法会导致这样的句柄泄漏吗?我最初确信它是 Process.Start() 但那将是 USER 句柄,不是吗?
编辑:
这是我如何创建流程的示例:
var pInfo = new ProcessStartInfo(path, ClientStartArguments)
{
UseShellExecute = false,
WorkingDirectory = workingDirectory
};
ClientProcess = Process.Start(pInfo);
这是我如何杀死同一个进程的示例(稍后在我与该进程交互后的程序中):
Process[] clientProcesses = Process.GetProcessesByName(ClientProcessName);
if (clientProcesses.Length > 0)
{
foreach (var clientProcess in clientProcesses.Where(
clientProcess => clientProcess.HasExited == false))
{
clientProcess.Kill();
}
}
【问题讨论】:
-
你打开的是什么进程,控制台还是windows应用?您是否打开了许多进程?
-
这是一个 Windows 应用程序。有时,我的应用程序会通过调用 Process.Kill() 并使用 Process.Start() 重新启动它来重新启动同一个应用程序。这是唯一使用 Process.Start() 打开的应用程序。
-
您是否在实例上调用 Dispose?如果不是,您可能正在泄漏句柄。
-
即使您可能没有泄漏内存,您也可能会泄漏启动新 Windows 应用程序所需的窗口句柄。
-
Process.Start 是一个静态方法,所以他无法处理它。此外,即使他正在启动 Process 的实例,它也不会拥有对不同进程中窗口句柄的引用。