2016-04-29 31 views
2

我们有一个用C++编写的服务,其中一些代码通过CLI在.NET中编写。由于第三方库在数据驱动的基础上覆盖了内存,因此我们被迫将主处理代码去除为单独的代码路径,其使用方式如下。使用特定的命令行参数运行服务EXE时,我们可以将整个服务作为控制台应用程序运行,绕过服务部分或作为仅执行处理的控制台应用程序。在主要操作模式中,服务正常启动并使用createprocess使用命令行参数启动它自己的可执行文件,该参数跳过服务初始化并进入处理部分。服务线程然后等待子进程完成并根据需要重复此过程。什么会导致进程停止重新创建?

我们遇到的问题是服务在1700子进程运行后无法启动自身的命令行版本。如果我们运气不好,服务也拒绝重启。服务拒绝重新启动时,内存中没有相关的进程。在服务失败后以命令行模式运行服务时,它将继续运行1700次子进程,直到它也失败。需要重新启动系统才能恢复服务/命令行进程的工作。我们还收到错误322 - “目标设备没有足够的资源来完成操作。”在事件日志中。我们已经移除了一个将子进程和父进程分组到一个单元的Job内核对象,这样当你终止父进程时,子进程也会终止。这增加了数千的1700限制。

windows是否有任何理由记得一个进程运行并会在重新运行时惩罚该进程?看起来,在不同的桌面或用户下运行的进程在这个问题上被视为单独的进程。当服务失败时,命令行版本可以运行并且会运行一段时间。这是否与桌面堆有关?我们同时在内存中永远不会有两个以上的进程。什么类型的窗口功能可以对进程产生持久影响,下一次在某个桌面/用户下运行?

+1

我有我的桌面堆的份额。请参阅http://geekswithblogs.net/akraus1/archive/2014/02/04/155370.aspx或许您也在泄漏桌面堆分配的对象。 Registerwindowmessage是一个很好的开始照顾。 –

回答

3

听起来就像你正在泄漏在父进程和子进程之间共享的内核资源。也许在每次启动一个子进程时,父进程会创建一个资源句柄并将其传递给(分享)给孩子,期待孩子关闭它,但是不能根据需要自行关闭它?

SysInternals实用程序可以帮助您诊断此问题。 HandleEx或Process Explorer启动,然后使用Process Monitor进行深入研究。

+1

桌面堆分配的对象(如Windows或窗口消息注册)通常对这些工具不可见。你需要使用内核调试器来监视当前的桌面堆或者你注入一个像dheapmon一样的内核驱动程序http://blog.airesoft.co.uk/2009/10/desktop-heap-monitor-vista-7/ –

+0

@ AloisKraus:在这种情况下,它似乎不太可能成为桌面堆对象。父母没有理由在每个孩子的基础上创建桌面堆对象,并且孩子创建的任何东西都应该照常清理。仍然值得检查,但我会首先检查内核对象。 –

相关问题