我们有一个用C ++编写的服务,其中包含一些.NET代码。由于第三方库在数据驱动的基础上覆盖了内存,因此我们不得不将主处理代码拆分为单独的代码路径,如下所示。使用特定命令行参数运行服务EXE时,我们可以将整个服务作为控制台应用程序运行,绕过服务部件或作为仅执行处理的控制台应用程序。在主要操作模式下,服务正常启动并使用createprocess以命令行参数启动它自己的可执行文件,该参数跳过服务初始化并进入处理部分。然后服务线程等待子进程完成并根据需要重复此过程。
我们遇到的问题是,在1700子进程运行后,服务无法启动自身的命令行版本。如果我们不够运气,该服务也拒绝重启。当服务拒绝重新启动时,内存中没有相关进程。在服务失败后以命令行模式运行服务时,它将继续执行子进程的1700次运行,直到它也失败。需要重新启动系统才能恢复服务/命令行进程的工作。我们也收到错误322 - “目标设备没有足够的资源来完成操作。”在事件日志中。我们已经删除了一个Job子对象,该对象将子进程和父进程分组为一个单元,这样当您终止父进程时,子进程也会终止。这使1700的限制增加了数千。
是否有任何理由为什么Windows会记住进程运行并在重新运行时对该进程进行处罚?似乎在不同桌面或用户下运行的进程被视为与此问题相关的单独进程。当服务失败时,命令行版本可以运行并且将运行一段时间。这与桌面堆有关吗?我们同时在内存中永远不会有两个以上的进程。什么类型的Windows函数可以对进程产生持久影响,下次在某个桌面/用户下运行?
答案 0 :(得分:3)
听起来你正在泄漏父进程和子进程之间共享的内核资源。也许在每次启动子进程时,父进程会创建一个资源的句柄并将其传递(共享)给子进程,期望子进程关闭它......但是不能根据需要自行关闭它?
SysInternals实用程序可以帮助您诊断这一点。 HandleEx或Process Explorer启动,然后使用Process Monitor。