2010-04-09 69 views
2

我正在開發一個.NET Windows服務,它正在創建一對線程,然後使用這些線程向打印機發送打印作業(每個線程都有一個線程打印機)。我有一些問題有時可以通過重新啓動服務來解決。當服務運行一段時間後,也會出現一些問題。這讓我懷疑可能會發生內存泄漏。於是,幾個問題:.NET Windows服務,線程和垃圾回收(可能的內存泄漏)

會一個垃圾收集器收集的對象,如果它是一個線程內創建,或者將物體存在,直到線程停止/終止?

我可以使用哪些工具來監視內存由Windows服務和由一個線程,我開始編程使用量?

+1

它可能是打印機代碼使用非託管代碼,它們保持在周圍而不是釋放。如果將打印代碼加載到單獨的應用程序域中,則至少可以卸載它以釋放內存並防止重新啓動服務。 – 2010-04-09 06:26:22

回答

3

所有對象內部創建的線程。每個執行的指令都在一個線程內。在沒有實時引用它們之後,對象將在某個時間點被垃圾收集。對象不屬於它們創建的線程。

對於監視服務,您可以使用perfmon其中有很多櫃檯的東西像垃圾回收的。要更詳細地分析你可能在哪裏泄漏物體,你應該使用一個分析器。如果您的程序也可以作爲非服務運行,所有這些可能會變得更簡單。 (你可能想出來分離成「啓動器」的一部分,然後,其可以從服務或從控制檯應用程序中使用的庫。)

0

在.NET垃圾收集器釋放了由對象保持的存儲器,其不再「可達」。爲了發現哪些對象「可訪問」(因此尚不符合垃圾收集條件),GC會暫停所有線程,從一組「根」對象開始,並嘗試遍歷整個圖形。每個沒有標記爲可達的對象都將成爲垃圾收集的候選對象。初始分配內存時哪個線程處於活動狀態並沒有什麼區別;重要的是在垃圾回收的第一階段,您的對象不再可訪問。 「根」包括所有局部變量和方法參數(這些是堆棧中每個服務線程的變量)和靜態變量。

Microsoft有一個名爲Debugging Tools for Windows的免費下載,其中包含windbg.exe。此工具可用於創建進程(私有)內存的轉儲。您可以調用它像這樣:windbg.exe -p <processID>

工具(與SOS擴展的幫助下)允許您導航可達對象自己。如果您的問題在於可用的託管對象過多,該工具應該能夠提供幫助。