我使用Windows 2003 R2和Windows 2008 R2與.NET框架4.0(64位)。與.net 4.0系統處理泄漏
我有一個OLTP的Windows服務,它偵聽套接字上的消息並創建線程來處理每條消息。該應用程序預計每秒處理多達200個事務,但負載會隨時變化(平均每天約80 TPS)。 我們面臨的問題是,由於某種原因,應用程序正在創建句柄,而不是擺脫它們。我已經使用了ProcessExplorer工具來查看正在增加的句柄是事件句柄,並且所有其他類型的句柄都會定期發佈。發生這種情況時,執行一兩天後,句柄計數增加太多,我的應用程序因OutOfMemory異常而崩潰。
我也使用ProcessExplorer驗證了所有未發佈的事件句柄都至少有一個引用。我的問題是我無法控制它們,因爲我的程序沒有明確地創建任何Handles。我自然毋庸置疑是在CLR和在調查後我發現https://connect.microsoft.com/VisualStudio/feedback/details/430646/thread-handle-leak#tabs 引用:」發佈Microsoft在2009年4月8日,在下午12:39
感謝您的反饋。我是公共語言運行時(CLR)團隊的線程開發人員。您報告的問題是CLR中的一個已知問題,我們正在努力在未來的版本中修復它。問題在於CLR線程句柄(和其他關聯的數據結構)由終結器線程清理,終止線程通常只響應垃圾回收(GC)而運行。如果在GC發生之前創建並銷燬很多線程(如果在此期間內存分配很少的情況下會出現這種情況),那麼它會產生「泄漏」句柄和內存的效果,並且在下次完成時會收回這些線程觸發。解決方法是通過調用GC.WaitForPendingFinalizers定期手動觸發終結。正如我所說的,我們正在努力在未來的CLR版本中糾正此問題。
發佈者埃德尼古拉斯4/7/2009 8:20 AM」 在同一頁上,微軟已經打上這個問題是固定的,但我看不出有任何引用到的CLR版本包含修復程序。
我已經閱讀過以下主題/鏈接。
Handle leaks with .NET System.Threading.Thread class
https://connect.microsoft.com/VisualStudio/feedback/details/430646/thread-handle-leak#
任何人都可以提出一個可行的解決方案?提前致謝。
Wajid侯賽因
您是否確定了手柄的來源?我傾向於說「修復bug並在完成時丟棄一次性對象,夥計」 - 任何創建句柄的對象都必須實現IDIsposable,並且它看起來忘記了處理這些對象(並依靠GC來清理對象) 。內存分析器應該可以幫助你分析問題。 – TomTom
即使使用5個句柄,Thread類也沒有Dispose()方法。出於一個相當好的理由,這將是非常困難的。 *非常*不太可能這是您的句柄泄漏的實際來源,兩天是*方式*太長,以解釋它。相反,尋找死鎖的終結器線程。 –
創建一個新的線程來處理每條消息似乎是一個很大的開銷,尤其是當您每秒處理多達200個事務時。看起來像你應該將消息排隊到一個'BlockingCollection'並且有幾個持久的消費者線程爲隊列提供服務。這會阻止您創建如此多的線程,從而避免泄漏事件句柄的問題。 –