Frage

Hier ist mein Szenario:

  1. Starten Sie mein Testprogramm und sofort brechen in den Debugger (WinDBG)
  2. Nehmen Sie ein! Dumpheap -stat und beobachten es keine System.Net sind * oder System.Xml * Objekte überall
  3. Erstellen Sie meine WCF-Client, stellen Sie einen WCF-Anforderung
  4. Schließen Sie den WCF-Client und Kraft GC.
  5. Nehmen Sie ein! Dumpheap -stat und Beobachter gibt es Tonnen von System.Net *, System.XML * Objekte noch im Speicher.

Also von meiner Beobachtung in Schritt # 5, sieht es aus wie WCF nicht richtig Aufräumen (oder eher ich bin etwas fehlt). Warum ist das? Wie kann ich den Speicher zurückzugewinnen, indem diese Objekte aufgenommen, die nicht hier sein sollte?

Hier ist mein Test-Code ...

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();
    }
}

P. S. Hier sind meine! FinalizeQueue Ergebnisse ... nicht sicher, ob dies relevant ist

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

Hinzufügen! Gcroot Spur von einem zufälligen Objekt, das ich denke, soll ... verschwunden sein

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)
War es hilfreich?

Lösung

Die XmlSerializer Architektur-Caches statisch alle Arten von Informationen über die Typen es aufgetreten ist, so dass es nicht ständig Serializer zu schaffen (was Sinn völlig macht), so ist es wirklich keine Überraschung für mich, dass diese Dinge sind nicht gereinigt Nach oben. Gemessen an der Tatsache, dass Ihr! Gcroot Dump mit Dingen aus der System.Xml.Serialization übersät ist, wie es scheint sicher, dass der Täter zu sein.

Andere Tipps

Was ist die Notwendigkeit, eine Garbage Collection zu erzwingen?

Wenn Ihr Kanal geschlossen ist, die CLR kümmert GC.

Check this out >>>

Haben Sie für die Wurzeln überprüfen?

ich entdecken, als in WinForms Tracing, dass Sie eine GC.Collect () zweimal mit einem Application.DoEvents zu tun haben () dazwischen auf undichte Stellen suchen Sammlung gut genug, um zu zwingen, eine Speicher-Tracer zu verwenden.

Ich wette das gleiche für WPF wahr ist.

Sie den Client auf null einstellen, bevor dispose auf Client aufgerufen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top