이러한 WCF 관련 리소스가 정리되지 않은 이유는 무엇입니까?
문제
내 시나리오는 다음과 같습니다.
- 내 테스트 프로그램을 시작하고 즉시 디버거 (WINDBG)에 침입하십시오.
- ! tumpheap -stat를 가져 가서 system.net* 또는 system.xml* 객체가 없음을 관찰하십시오.
- 내 WCF 클라이언트를 만들고 WCF 요청을하십시오
- WCF 클라이언트를 닫고 GC를 강제로 닫으십시오.
- ! tumpheap -stat를 가져 가십시오.
따라서 5 단계 #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();
}
}
추신 : 여기에 내! 최종화물 결과가 있습니다 ... 이것이 관련이 있는지 확실하지 않습니다.
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
추가! 내가 사라져야한다고 생각하는 임의의 물체의 추적 ...
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의 물건으로 가득 차 있다는 사실로 판단하면, 그것은 원인 인 것 같습니다.
다른 팁
뿌리를 확인 했습니까?
Winforms에서 추적 할 때 application.doevents ()를 두 번 gc.collect ()를 두 번 수행해야한다는 것을 발견했습니다.
WPF에 대해서도 마찬가지입니다.
클라이언트를 처분하기 전에 클라이언트를 NULL로 설정하고 있습니다.
제휴하지 않습니다 StackOverflow