これらのWCF関連のリソースがクリーンアップされないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/1640256

質問

ここに私のシナリオがあります:

  1. テストプログラムを開始し、すぐにデバッガーに侵入します(WinDBG)
  2. !DumpHeap -statを実行して、System.Net *またはSystem.Xml *オブジェクトがどこにも存在しないことを確認します
  3. WCFクライアントを作成し、WCFリクエストを行う
  4. WCFクライアントを閉じて、GCを強制します。
  5. !DumpHeap -statとオブザーバーを使用して、大量のSystem.Net *、System.Xml *オブジェクトがまだメモリに残っている。

したがって、ステップ5での観察から、WCFが適切にクリーンアップされていないように見えます(または、おそらく何かが欠落しています)。どうしてこれなの?ここにあるべきではないこれらのオブジェクトによって占有されたメモリをどのように回収できますか?

ここに私のテストコードがあります...

class Program
{
    static void Main(string[] args)
    {
        Debugger.Break();
        // !DumpHeap -stat here indicates no System.Net* or System.Xml* objects


        BasicHttpBinding binding = new BasicHttpBinding();
        binding.Security.Mode = BasicHttpSecurityMode.None;
        binding.UseDefaultWebProxy = false;
        WcfClient client = new WcfClient(
            binding, new EndpointAddress("http://myserver.com/service.svc"));
        client.Endpoint.Binding = binding;
        client.GetChain(new GetChainType()); // WCF call

        // my ineffective clean up code
        client.Close();
        client = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();


        // !DumpHeap -stat here indicates many System.Net* or System.Xml* objects

        Console.WriteLine("Request complete, press enter to quit");
        Console.ReadLine();
    }
}

PSここに私の!FinalizeQueueの結果があります...これが関連するかどうかわからない

0:010> !FinalizeQueue
SyncBlocks to be cleaned up: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
generation 0 has 1 finalizable objects (000000001b1527f8->000000001b152800)
generation 1 has 81 finalizable objects (000000001b152570->000000001b1527f8)
generation 2 has 0 finalizable objects (000000001b152570->000000001b152570)
Ready for finalization 0 objects (000000001b152800->000000001b152800)
Statistics:
              MT    Count    TotalSize Class Name
000007fef033d078        1           32 Microsoft.Win32.SafeHandles.SafePEFileHandle
000007fef0326ab0        1           32 System.Security.Cryptography.SafeProvHandle
000007fef0326680        1           32 Microsoft.Win32.SafeHandles.SafeTokenHandle
000007feef7a2c18        1           32 Microsoft.Win32.SafeHandles.SafeProcessHandle
000007feef7a2b78        1           32 Microsoft.Win32.SafeHandles.SafeFileMapViewHandle
000007feef7a2ad8        1           32 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
000007feef793510        1           32 System.Net.SafeLocalFree
000007feef78d980        1           40 System.Net.SafeCloseSocket
000007feef7a34e8        1           48 Microsoft.CSharp.CSharpCodeProvider
000007fef030fb18        2           64 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
000007fef030fa78        2           64 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle
000007feef791048        1           80 System.Net.Sockets.NetworkStream
000007fef03101f8        3           96 Microsoft.Win32.SafeHandles.SafeFileHandle
000007feef78caa0        1          120 System.Net.Sockets.Socket
000007fef02fdd10        2          128 System.Threading.ReaderWriterLock
000007feef78f520        4          160 System.Net.SafeRegistryHandle
000007feef78cd08        5          160 System.Net.SafeCloseSocket+InnerSafeCloseSocket
000007feef78f368        4          192 System.Net.SafeCloseSocketAndEvent
000007fef03071f8        2          208 System.Threading.Thread
000007fef02ffc40        7          224 Microsoft.Win32.SafeHandles.SafeRegistryHandle
000007fef02f4978       10          320 Microsoft.Win32.SafeHandles.SafeWaitHandle
000007fef02fdc70       20          640 System.WeakReference
000007feef7a1de0       10         1680 System.Diagnostics.PerformanceCounter
Total 82 objects

削除すべきだと思うランダムオブジェクトの!GCRootトレースを追加...

0:010> !GCRoot -nostacks 000000000288e110 
DOMAIN(000000000020B2B0):HANDLE(Pinned):e17b8:Root:0000000012840770(System.Object[])->
00000000028b5380(System.Collections.Hashtable)->
00000000028b53d8(System.Collections.Hashtable+bucket[])->
00000000028b5528(System.Collections.Hashtable)->
00000000028b5580(System.Collections.Hashtable+bucket[])->
00000000028c1f68(Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer)->
0000000002898a38(System.Xml.Serialization.XmlMembersMapping)->
0000000002898a70(System.Object[])->
0000000002898a98(System.Xml.Serialization.XmlMemberMapping)->
0000000002896950(System.Xml.Serialization.MemberMapping)->
00000000028b90a8(System.Object[])->
00000000028969b8(System.Xml.Serialization.ElementAccessor)->
0000000002896aa8(System.Xml.Serialization.StructMapping)->
0000000002895eb8(System.Xml.Serialization.StructMapping)->
00000000028928f8(System.Xml.Serialization.StructMapping)->
000000000288bd10(System.Xml.Serialization.StructMapping)->
0000000002890da8(System.Xml.Serialization.StructMapping)->
000000000288f8e8(System.Xml.Serialization.StructMapping)->
000000000288ea78(System.Xml.Serialization.StructMapping)->
000000000288dc70(System.Xml.Serialization.StructMapping)->
000000000288dd20(System.Xml.Serialization.NameTable)->
000000000288dd38(System.Collections.Hashtable)->
000000000288dd90(System.Collections.Hashtable+bucket[])->
000000000288e1f8(System.Xml.Serialization.AttributeAccessor)->
000000000288e2f0(System.Xml.Serialization.EnumMapping)->
000000000288e110(System.Xml.Serialization.TypeDesc)
役に立ちましたか?

解決

XmlSerializerアーキテクチャは、発生した型に関するすべての種類の情報を静的にキャッシュするため、常にシリアライザーを作成する必要はありません(完全に理にかなっています)。アップ。 !GCRootダンプがSystem.Xml.Serializationからのもので散らばっているという事実から判断すると、間違いなく犯人のようです。

他のヒント

ガベージコレクションを強制する必要性は何ですか?

チャンネルが閉じている場合、CLRがGCを処理します。

これをチェックout>>>

ルートを確認しましたか?

WinFormsでトレースするときに、メモリトレーサーを使用してリークを探すのに十分な収集を強制するために、間にApplication.DoEvents()でGC.Collect()を2回行う必要があることを発見しました。

WPFについても同じことが当てはまります。

クライアントでdisposeが呼び出される前に、クライアントをnullに設定しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top