在托管进程中查找令牌句柄泄漏的来源

时间:2017-01-05 22:16:53

标签: c# wcf memory-leaks windbg handle

我正在研究在.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的评论之后,我注意到线程句柄数量也在增加 - 我之前因为大量的令牌句柄而忽略了这一点。

0 个答案:

没有答案