我正在研究在.NET 4.6.2上运行的WCF服务中的句柄泄漏。该服务运行良好但随着时间的推移,句柄数量不断增加,在此过程中有数千个Token
类型句柄。看起来内存也在缓慢泄漏(可能与手柄泄漏有关)。
编辑:看起来事件和线程句柄也被泄露了。
Process Explorer显示所有可疑句柄都具有相同的名称:
DOMAIN\some.username$:183db90
并且所有人都拥有相同的地址。
我将WinDbg附加到该流程并稍后运行!htrace -enable
然后!htrace -diff
。这给了我一个近2000个新打开的句柄和本机堆栈跟踪的列表,如下所示:
Handle = 0x000000000000b02c - OPEN
Thread ID = 0x000000000000484c, Process ID = 0x0000000000002cdc
0x00007ffc66e80b3a: ntdll!NtCreateEvent+0x000000000000000a
0x00007ffc64272ce8: KERNELBASE!CreateEventW+0x0000000000000084
0x00007ffc5b392e0a: clr!CLREventBase::CreateManualEvent+0x000000000000003a
0x00007ffc5b3935c7: clr!Thread::AllocHandles+0x000000000000007b
0x00007ffc5b3943c7: clr!Thread::CreateNewOSThread+0x000000000000007f
0x00007ffc5b394308: clr!Thread::CreateNewThread+0x0000000000000090
0x00007ffc5b394afb: clr!ThreadpoolMgr::CreateUnimpersonatedThread+0x00000000000000cb
0x00007ffc5b394baf: clr!ThreadpoolMgr::MaybeAddWorkingWorker+0x000000000000010c
0x00007ffc5b1d8c74: clr!ManagedPerAppDomainTPCount::SetAppDomainRequestsActive+0x0000000000000024
0x00007ffc5b1d8d27: clr!ThreadpoolMgr::SetAppDomainRequestsActive+0x000000000000003f
0x00007ffc5b1d8cae: clr!ThreadPoolNative::RequestWorkerThread+0x000000000000002f
0x00007ffc5a019028: mscorlib_ni+0x0000000000549028
0x00007ffc59f5f48f: mscorlib_ni+0x000000000048f48f
0x00007ffc59f5f3b9: mscorlib_ni+0x000000000048f3b9
另一个堆栈跟踪(~2000个新句柄的很大一部分都有这个):
Handle = 0x000000000000a0c8 - OPEN
Thread ID = 0x0000000000003614, Process ID = 0x0000000000002cdc
0x00007ffc66e817aa: ntdll!NtOpenProcessToken+0x000000000000000a
0x00007ffc64272eba: KERNELBASE!OpenProcessToken+0x000000000000000a
0x00007ffc5a01aa9b: mscorlib_ni+0x000000000054aa9b
0x00007ffc5a002ebd: mscorlib_ni+0x0000000000532ebd
0x00007ffc5a002e68: mscorlib_ni+0x0000000000532e68
0x00007ffc5a002d40: mscorlib_ni+0x0000000000532d40
0x00007ffc5a0027c7: mscorlib_ni+0x00000000005327c7
0x00007ffbfbfb3d6a: +0x00007ffbfbfb3d6a
当我在WinDbg中运行!handle 0 0
命令时,我得到以下结果:
21046 Handles
Type Count
None 4
Event 2635 **
Section 360
File 408
Directory 4
Mutant 9
Semaphore 121
Key 77
Token 16803 **
Thread 554 **
IoCompletion 8
Timer 3
TpWorkerFactory 2
ALPC Port 7
WaitCompletionPacket 51
标有**
的标签随着时间的推移而增加,但速度不同。
编辑3:
我运行了!dumpheap
来查看Thread
个对象(删除了不相关的类)的数量:
!DumpHeap -stat -type System.Threading.Thread
Statistics:
MT Count TotalSize Class Name
00007ffc5a152bb0 745 71520 System.Threading.Thread
当进程正在定期处理某些后台任务时,活动线程计数在Process Explorer中在56和62之间波动。
某些堆栈跟踪不同,但它们都是本机跟踪,因此我不知道托管代码触发了句柄创建。调用Thread::CreateNewThread
时,是否可以在新创建的线程上运行托管函数调用?我不知道我为此使用了什么WinDbg命令。
注意: 我无法将示例代码附加到问题中,因为WCF服务加载了数百个DLL-s,其中大多数都是从许多源文件构建的 - 我对这可能来自哪个主要领域有一些非常模糊的怀疑,但我不知道知道任何细节以显示MCVE。
编辑:在Harry Johnston的评论之后,我注意到线程句柄数量也在增加 - 我之前因为大量的令牌句柄而忽略了这一点。