我有一个用.NET 4.0开发的应用程序。此应用程序在某些自定义性能计数器上跟踪并显示给用户。最近我发现应用程序中有句柄泄漏。这两种句柄是变体和PcwObject。
我跟踪了这个页面(http://blogs.technet.com/b/yongrhee/archive/2011/12/19/how-to-troubleshoot-a-handle-leak.aspx)并获得了以下堆栈跟踪:
Handle = 0x0000000000003760 - OPEN
Thread ID = 0x00000000000073d0, Process ID = 0x0000000000005fdc
0x0000000077c41cea: ntdll!NtCreateMutant+0x000000000000000a
0x000007fefde08bf7: KERNELBASE!CreateMutexExW+0x000000000000004f
0x000007fefde14460: KERNELBASE!CreateMutexExA+0x0000000000000038
0x000007feff6bbcf6: ADVAPI32!PerflibciOpenLocalQueryHandle+0x0000000000000116
0x000007feff6a5a86: ADVAPI32!PerflibciQueryV2Provider+0x000000000000020d
0x000007feff68926d: ADVAPI32!QueryExtensibleData+0x00000000000004a2
0x000007feff6898e4: ADVAPI32!alloca_probe+0x00000000000051b2
0x00000000779d4087: KERNEL32!TlsGetValue+0x000000000000fbb8
0x00000000779e4b52: KERNEL32!RegQueryValueExW+0x00000000000000f2
0x000007feff68c2ed: ADVAPI32!RegQueryValueExWStub+0x000000000000001d
0x000007fef99b17c7: clr!DoNDirectCall__PatchGetThreadCall+0x000000000000007b
0x000007fef8a38422: mscorlib_ni+0x0000000000428422
0x000007fef89948f1: mscorlib_ni+0x00000000003848f1
0x000007fef899392e: mscorlib_ni+0x000000000038392e和
Handle = 0x0000000000003998 - OPEN
Thread ID = 0x0000000000002808, Process ID = 0x0000000000005fdc
0x0000000077c4138a: ntdll!NtDeviceIoControlFile+0x000000000000000a
0x000007fefce214a3: pcwum!PcwpSendIoctl+0x00000000000000f3
0x000007fefce21962: pcwum!PcwCreateNotifier+0x000000000000003e
0x000007feff6abf53: ADVAPI32!PerfpCreateProvider+0x00000000000000d3
0x000007feff6ddb77: ADVAPI32!PerflibciLocalValidateCounters+0x0000000000000167
0x000007feff6a5ced: ADVAPI32!PerflibciQueryV2Provider+0x0000000000000478
0x000007feff68926d: ADVAPI32!QueryExtensibleData+0x00000000000004a2
0x000007feff6898e4: ADVAPI32!alloca_probe+0x00000000000051b2
0x00000000779d4087: KERNEL32!TlsGetValue+0x000000000000fbb8我还打开来监视句柄状态。根据我的观察,上面的两个手柄(3760和3998)活了半个多小时,还没有被摧毁。手柄计数在2小时内增加了~1000。其中一半是突变体,另一半是PcwObject。
我怀疑它与PerformanceCounter有关,因为我知道注册表中的PerformanceCounter类grep数据,并且我在堆栈跟踪中找到了PerflibciQuery和RegQueryValue。
我在网上搜索过,但似乎没有运气。有人知道这件事吗?谢谢
附加信息
我一个接一个地测试了这些性能计数器,发现这些句柄在得到这个计数器:PerformanceCounter("HTTP Service Request Queues", "CurrentQueueSize", "ABC")时被泄露了。
我的守则如下:
private PerformanceCounter counter;
private void Detect()
{
/*
Do sth
*/
try
{
if (null == counter) counter = new PerformanceCounter("HTTP Service Request Queues", "CurrentQueueSize", "ABC");
long rawValue = counter.RawValue;
if (0 < rawValue)
WriteLog("ABC CurrentQueueSize: {0}", rawValue);
}
catch(Exception e)
{
WriteLog("Fail to get ABC counter. {0}", e);
}
}counter是一个成员变量,我非常肯定,当这个类被销毁时,它会被释放。所以我不知道它为什么会漏手柄。
发布于 2014-08-29 02:53:26
我几天前就已经找到原因了,但忘了发出去了。对此我很抱歉。
实际上,这是使用v2 PerformanceCounter (http://support.microsoft.com/kb/2734909)造成的资源泄漏。然后我遵循了这个页面中的指令(http://msdn.microsoft.com/en-us/library/aa392740(v=vs.85).aspx并发现“”是一个v2计数器提供程序。
这就是原因所在!完成了!
发布于 2014-08-20 13:20:31
我最近注意到,如果您在另一个线程中向计数器请求一个值,则会发现句柄泄漏。如果您创建了一个新线程,请询问性能计数器的下一个值,它将创建一堆即使您释放计数器也不会被清理的处理。
https://stackoverflow.com/questions/25160880
复制相似问题