簡體   English   中英

WCF服務中無法解釋的線程創建和句柄計數增加

[英]Unexplained thread creation and handle count increase in a WCF service

我們在具有32個核心的Server 2008 R2 Amazon EC2實例上的IIS上托管了多個WCF服務。 我們正在使用.NET Framework 4.5.2版。 當前的問題是無法解釋的句柄數量增加-我們的某些服務在活動超過一天后會累積成千上萬的打開句柄(當我使用第3方工具強制進行垃圾收集時,句柄計數降至2k左右) 。 為了對此進行調查,我創建了一個沒有功能的簡單服務,並在IIS下啟動了它。 沒有客戶端請求對此服務。 在一個小時內,根據服務流程,有2萬多個把手打開。 使用procmon查看服務的過程,我發現每40秒左右就會有20多個線程退出,然后創建線程。 然后,我將該服務的應用程序池從.NET Framework版本v4.0切換到了v2.0,然后再次啟動該服務。 整個小時中,手柄數並未從大約500個打開的手柄中移出。 我無法在多台機器上重現此問題(不是在Amazon上)。 我知道CLR 4.0中有顯着的線程池更改-http: //msdn.microsoft.com/zh-cn/magazine/ff960958.aspx ,但我不知道為什么會看到1)線程爆發沒有客戶端請求或服務未執行工作的創建活動; 2)為什么未釋放線程句柄和關聯的事件句柄。

我最近遇到了一個.NET服務(托管在帶有.NET 4.5.1的Server 2012 R2上的IIS中)的問題。 閑置時,它將積累> 30,000個手柄。 在WinDbg中使用!htrace ,我可以看到所有在該堆棧中創建的句柄:

Call Site
clr!Thread::CreateNewOSThread+0x7f
clr!Thread::CreateNewThread+0x90
clr!ThreadpoolMgr::CreateUnimpersonatedThread+0xc7
clr!ThreadpoolMgr::MaybeAddWorkingWorker+0x113
clr!ManagedPerAppDomainTPCount::SetAppDomainRequestsActive+0x24
clr!ThreadpoolMgr::SetAppDomainRequestsActive+0x2a
clr!ThreadPoolNative::RequestWorkerThread+0x2b
mscorlib_ni!System.Threading.ThreadPoolWorkQueue.Dispatch()
mscorlib_ni![ContextTransitionFrame: 0000002b15e4ef28] 
clr!CallDescrWorkerInternal+0x83
clr!CallDescrWorkerWithHandler+0x4a
clr!MethodDescCallSite::CallTargetWorker+0x380
clr!QueueUserWorkItemManagedCallback+0x2a
clr!ManagedThreadBase_DispatchInner+0x2d
clr!ManagedThreadBase_DispatchMiddle+0x6c
clr!ManagedThreadBase_DispatchOuter+0x75
clr!ManagedThreadBase_DispatchInCorrectAD+0x15
clr!Thread::DoADCallBack+0x25b
clr!ManagedThreadBase_DispatchInner+0x69
clr!ManagedThreadBase_DispatchMiddle+0x6c
clr!ManagedThreadBase_DispatchOuter+0x75
clr!ManagedThreadBase_FullTransitionWithAD+0x2f
clr!ManagedPerAppDomainTPCount::DispatchWorkItem+0xe3
clr!ThreadpoolMgr::ExecuteWorkRequest+0x64
clr!ThreadpoolMgr::WorkerThreadStart+0x2b6
clr!Thread::intermediateThreadProc+0x7d
KERNEL32!BaseThreadInitThunk+0xd
ntdll!RtlUserThreadStart+0x1d

每次對CreateNewOSThread的調用都將創建1個線程句柄和4個事件句柄,這些句柄沒有被清理(線程將完成運行,但這些句柄會一直存在)。 我從未跟蹤過向線程池添加任務的內容,但是我注意到的是,由於服務是“空閑”的,因此從未調用過GC。

出於某種原因,當允許工作線程退出時,線程池管理器不會釋放該句柄,而是依靠垃圾回收器來完成。

作為測試,我添加了一種方法來手動調用服務上的垃圾收集器。 觀察到句柄的線性增加后,我在服務上啟動了GC,並觀察到句柄數下降到正常水平。

在托管一個WCF服務的w3wp.exe實例中,.NET 4中至少存在3個AppDomain,一個稱為SharedAppDomains,其中包括20多個.net框架程序集,另一個稱為Default,最后一個名稱類似於/ LM / W3Svc ....一些時髦的名稱,其中包含您的WCF應用程序程序集以及一些直接依賴項。 哪種工具告訴您只有一個應用程序域不包含其他程序集? 最簡單的方法是以管理員身份運行Process Explorer 然后檢查w3wp.exe實例的.NET程序集。

但是,即使WCF處於空閑狀態而不響應即將到來的請求,w3wp.exe也不會處於空閑狀態,因為w3wp.exe是一個托管進程,負責執行許多內部任務。 在Windows 7上IIS 7的.net 4應用程序池上的.NET 4.5.1上的Hello World WCF服務中,w3wp.exe的線程數在44-47之間跳躍。 內存使用以及其他資源數字基本穩定。

您提到的問題僅發生在AWS機器上,而不是其他機器上。 因此,您最好通過以Administrator身份運行Process Explorer來查找所有已加載的應用程序域及其程序集,並在您自己的PC上比較w3wp.exe實例的列表,並找出一些可能比預期做得更多的常見嫌疑人。 當然,這可能是w3wp.exe受到威脅並正在做一些雜事,但是,在此階段,只需先檢查程序集和應用程序域即可。 這不是答案,但是,SO的注釋區域對注釋的長度有所限制。 因此,希望這是開始檢查問題的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM