2016-04-29 46 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:在這種情況下,它似乎不太可能成爲桌面堆對象。父母沒有理由在每個孩子的基礎上創建桌面堆對象,並且孩子創建的任何東西都應該照常清理。仍然值得檢查,但我會首先檢查內核對象。 –

相關問題