繁体   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