0

.NET 4.0 で開発されたアプリケーションがあります。このアプリケーションは、いくつかのカスタム パフォーマンス カウンターを追跡し、ユーザーに表示します。最近、アプリケーションにハンドル リークがあることがわかりました。Mutant と PcwObject の 2 種類のハンドルがあります。

このページ ( 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

また、ハンドルの状態を監視するために Process Explorer も開きました。私の観察によると、上記の 2 つのハンドル (3760 と 3998) は 30 分以上存続し、まだ破壊されていません。ハンドル数は 2 時間以内に最大 1000 増加します。それらの半分は Mutant で、残りの半分は PcwObject です。

PerformanceCounter coz に関連していると思われます。レジストリからの PerformanceCounter クラスの grep データを知っており、スタック トレースで PerflibciQuery と RegQueryValue を見つけました。

インターネットで検索しましたが、うまくいかないようです。誰かこれについて何か考えがありますか?ありがとう

追加情報

これらのパフォーマンス カウンターを 1 つずつテストしたところ、このカウンターを取得するときにこれらのハンドルがリークしていたことがわかりました。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はメンバー変数であり、このクラスが破棄されると破棄されると確信しています。だから、ハンドルが漏れる理由がわかりません。

4

2 に答える 2

0

最近気付いたのは、別のスレッドでカウンターに値を要求した場合のハンドル リークです。新しいスレッドを作成する場合は、パフォーマンス カウンターに次の値を要求します。これにより、カウンターを破棄してもクリーンアップされない一連のハンドルが作成されます。

于 2014-08-20T13:20:31.383 に答える