以下是我的情景:

  1. 启动我的测试程序并立即进入调试器(WinDBG)
  2. 拿一个!DumpHeap -stat并观察到没有System.Net *或System.Xml *对象
  3. 创建我的WCF客户端,发出WCF请求
  4. 关闭WCF客户端并强制GC。
  5. 拿一个!DumpHeap -stat和观察者有大量的System.Net *,System.Xml *对象仍在内存中。
  6. 因此,根据我在步骤#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();
        }
    }
    

    P.S。这是我的!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。

检查此项出>>>

你检查了根源吗?

我发现在WinForms中进行跟踪时,您必须使用两次之间的Application.DoEvents()来执行GC.Collect()两次强制收集,以便使用内存跟踪器来查找泄漏。

我敢打赌WPF也是如此。

在客户端调用dispose之前,您将客户端设置为null。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top