我们的WCF服务显示出大量内存使用,因此我们进行了完整的内存转储以确定问题。
Operating System Windows Server 2008 R2Service Pack 1
Number Of Processors 4
Process Image c:\Windows\System32\inetsrv\w3wp.exe
System Up-Time 40 day(s) 09:23:09
Process Up-Time 14 day(s) 11:49:01
.NET 4.0
Processor Type X64
Process Bitness 64-Bit
从DebugDiag报告中的全局视角看问题。
进程正在进行垃圾回收,所以根据警告,我不应该信任!heap命令的所有输出。
Gc堆:1.37 G字节
.NET缓存大小为750Mb,
虚拟内存详细信息:
虚拟分配:17.45 Gb
已加载模块:208.68 Mb
线程:25 Mb
本机堆:3.06 Gb(我对此感到担忧。)
以上3.02 Gb
仅存在于Heap 0x003f0000
上。
我们有大量的流量,因此1.3 gb
的Gc堆大小对我来说感觉很正常。此外,我们拥有32 gb
内存和64位地址空间的机器,因此750 mb
的缓存大小是可以接受的。根据本机堆的大小,我认为这是本机内存泄漏。
DebugDiag警告:转储文件中有18149个动态程序集加载。
帮助链接:
.NET内存泄漏:通过XmlSerializing方式导致内存泄漏
分析-我们确实使用XmlSerialisers,但它们被缓存,这样它们只会被创建一次。
.NET内存泄漏:XslCompiledTransform和泄漏的动态程序集
我们似乎有与此博客文章描述的相同问题。所有这些18149个动态程序集的大小都为0。因此,我无法转储它们以获取详细信息。此外,我们在此应用程序中没有使用Xsl变换。因此,这些程序集不是由于Xsl变换而产生的。
更多统计数据:
相关对象计数:
System.Reflection.Emit.InternalModuleBuilder ----- 1.11 MBytes (18149 objects )
System.Reflection.Emit.InternalAssemblyBuilder ----- 992.52 KBytes (18149 objects )
System.Reflection.Emit.__FixupData[] ---------- 595.41 KBytes (752 objects )
System.Reflection.Emit.GenericFieldInfo ---------- 580.03 KBytes (18561 objects )
System.Reflection.RuntimeMethodInfo ---------- 1.2 MBytes (11276 objects )
System.RuntimeType -------------------- 1.13 MBytes (21228 objects )
Finalizer队列中的顶级对象
System.Reflection.Emit.DynamicResolver - 379
System.Reflection.Emit.DynamicResolver+DestroyScout - 271
应用程序域统计信息
Domain - Default - 13个程序集 - 大小:89,677,824(90 Mb〜)
Domain - ROOT/tv/Engine1 - 18236个程序集 - 大小:152,834,048(150 Mb〜)
我猜这些泄漏的动态程序集占用了150 Mb的空间。不确定3 Gb的本机内存是否归因于这些程序集?
深入挖掘这些程序集:
!dumpdomain
向我显示以下未知的大型动态程序集:
Assembly: 000000000fa9d0d0 (Dynamic) []
ClassLoader: 0000000002be1d40
SecurityDescriptor: 000000000fc08a00
Module Name
000007fe96d38e68 Dynamic Module
and !EEHeap -loader gives same number of 0 sized modules :
Module 000007fea0b7b758: Size: 0x0 (0) bytes.
Module 000007fea0b7c1e8: Size: 0x0 (0) bytes.
Module 000007fea0b7cc78: Size: 0x0 (0) bytes.
从以下堆栈跟踪来看,检查了是否阻塞了GC Finalizer线程,但并非如此。它正在等待终结事件的发生。
0:000> ~20 k
Child-SP RetAddr Call Site
00000000`0eedf3b8 000007fe`fd6f1430 ntdll!ZwWaitForMultipleObjects+0xa
00000000`0eedf3c0 00000000`77501723 KERNELBASE!WaitForMultipleObjectsEx+0xe8
00000000`0eedf4c0 000007fe`f60939d4 kernel32!WaitForMultipleObjectsExImplementation+0xb3
00000000`0eedf550 000007fe`f6094799 clr!SVR::WaitForFinalizerEvent+0xcc
00000000`0eedf590 000007fe`f5f0458c clr!SVR::GCHeap::FinalizerThreadWorker+0x4a
00000000`0eedf5d0 000007fe`f5f0451a clr!Frame::Pop+0x50
Dump中泄漏的动态程序集数量与 System.Reflection.Emit.InternalModuleBuilder
和 System.Reflection.Emit.InternalAssemblyBuilder
对象数量相同。我注意到 Top finalizer 队列中有 System.Reflection.Emit.DynamicResolver
,并转储了所有这些对象,并将其与动态程序集地址相对应。转储了约 5 个 DynamicResolver 对象,并跟踪了 DynamicResolver -> m_method -> m_module (00000001801728a0)
。其中一个模块的地址是 00000001801728a0
,来自 InternalModuleBuilder 列表。它们中的大部分指向相同的模块。0:000> !dumpheap -type System.Reflection.Emit.DynamicResolver
Address MT Size
000000018017d5a8 000007fef4c7c8b0 72
000000018018d5b0 000007fef4c7c8b0 72
00000001801931b0 000007fef4c7c8b0 72
------- and on
0:000> !do 000000018017d5a8
Name: System.Reflection.Emit.DynamicResolver
MethodTable: 000007fef4c7c8b0
EEClass: 000007fef4754300
Size: 72(0x48) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007fef4c44458 4002aaa 8 System.Object[] 0 instance 0000000000000000 m_exceptions
000007fef4c9a690 4002aab 10 System.Byte[] 0 instance 0000000000000000 m_exceptionHeader
000007fef4ca20c0 4002aac 18 ...mit.DynamicMethod 0 instance 0000000180172690 m_method
000007fef4c9a690 4002aad 20 System.Byte[] 0 instance 000000018017d5f0 m_code
000007fef4c9a690 4002aae 28 System.Byte[] 0 instance 000000018017d650 m_localSignature
000007fef4c992b8 4002aaf 38 System.Int32 1 instance 3 m_stackSize
000007fef4c7c788 4002ab0 30 ...Emit.DynamicScope 0 instance 0000000180172b80 m_scope
0:000> !do 0000000180172690
Name: System.Reflection.Emit.DynamicMethod
MethodTable: 000007fef4ca20c0
EEClass: 000007fef475e298
Size: 112(0x70) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007fef4c44458 4002ac6 8 System.Object[] 0 instance 0000000180172700 m_parameterTypes
000007fef4cafa88 4002ac7 10 ...RuntimeMethodInfo 0 instance 000000018017d678 m_methodHandle
000007fef4c987f8 4002ac8 18 System.RuntimeType 0 instance 00000004800e7900 m_returnType
000007fef4c7c578 4002ac9 20 ...ynamicILGenerator 0 instance 0000000180172a30 m_ilGenerator
000007fef4c4eb18 4002aca 28 ...mit.DynamicILInfo 0 instance 0000000000000000 m_DynamicILInfo
000007fef4c97de0 4002acb 60 System.Boolean 1 instance 1 m_fInitLocals
000007fef4c9f1d8 4002acc 30 ...ion.RuntimeModule 0 instance 00000001801728a0 m_module
000007fef4c97de0 4002acd 61 System.Boolean 1 instance 0 m_skipVisibility
000007fef4c987f8 4002ace 38 System.RuntimeType 0 instance 0000000000000000 m_typeOwner
000007fef4c7c330 4002acf 40 ...d+RTDynamicMethod 0 instance 00000001801729d8 m_dynMethod
000007fef4c7c8b0 4002ad0 48 ...t.DynamicResolver 0 instance 000000018017d5a8 m_resolver
000007fef4c97de0 4002ad1 62 System.Boolean 1 instance 0 m_profileAPICheck
000007fef4c99d18 4002ad2 50 ...n.RuntimeAssembly 0 instance 0000000000000000 m_creatorAssembly
000007fef4c97de0 4002ad3 63 System.Boolean 1 instance 1 m_restrictedSkipVisibility
000007fef4c88d70 4002ad4 58 ...g.CompressedStack 0 instance 00000001801729b0 m_creationContext
000007fef4c88020 4002ad5 16b8 ...rnalModuleBuilder 0 shared static s_anonymouslyHostedDynamicMethodsModule
>> Domain:Value 0000000002b66ba0:NotInit 0000000002c24a90:00000001801728a0 <<
000007fef4c96ae8 4002ad6 16c0 System.Object 0 shared static s_anonymouslyHostedDynamicMethodsModuleLock
>> Domain:Value 0000000002b66ba0:NotInit 0000000002c24a90:0000000180172798 <<
Opened log file 'C:\debug\new_dynamic_asm.log'
0:000> !dumpheap -type System.Reflection.Emit.InternalModuleBuilder
Address MT Size
00000001800fe918 000007fef4c88020 64
00000001801728a0 000007fef4c88020 64
000000018017fa88 000007fef4c88020 64
00000001801bee20 000007fef4c88020 64
------- and on
我对WinDbg不太熟悉,有人可以给我一些提示吗?
- 如何将上述动态模块与错误代码联系起来。我认为这是由于Linq或Lambda表达式引起的。
- 根据报告,动态程序集的大小为150 Mb,3 Gb泄漏是否有所不同,或者动态模块可能链接到某些本地内存。
!heap -l 给出了:188722个潜在的无法访问的块被检测到。
使用WinDbg PyKd插件的本机堆统计信息给出了以下本机堆的统计信息。
请注意值在18,000左右徘徊。
Statistics:
Type name Count Size
clr!RecordPool 817335 Unknown
clr!RegMeta 272445 Unknown
clr!CBlobPoolHash 36326 Unknown
clr!MDInternalRW 36326 Unknown
clr!StgBlobPool 36326 Unknown
clr!CCeeGen 36298 Unknown
clr!PEAssembly 18267 Unknown
clr!AssemblySecurityDescriptor 18249 Unknown
clr!DomainAssembly 18249 Unknown
clr!SharedSecurityDescriptor 18236 Unknown
clr!CStringPoolHash 18163 Unknown
clr!CMiniMdRW 18163 Unknown
clr!StgGuidPool 18163 Unknown
clr!StgStringPool 18163 Unknown
clr!CCustAttrHash 18163 Unknown
clr!CGuidPoolHash 18163 Unknown
clr!PESectionMan 18149 Unknown
clr!CeeSectionString 18149 Unknown
clr!PESection 18149 Unknown
nativerd!CONFIG_ELEMENT 4932 Unknown
nativerd!ATTRIBUTE_VALUE 3912 Unknown
nativerd!SCHEMA_ATTRIBUTE 1473 Unknown
clr!CAssemblyName 1116 Unknown
nativerd!COLLECTION_KEY_ENTRY 919 Unknown
nativerd!SCHEMA_ELEMENT 766 Unknown
clr!AssemblyMDInternalImport 720 Unknown
nativerd!CONFIG_SECTION 652 Unknown
nativerd!CONFIG_COLLECTION 570 Unknown
clr!ListNode<CHashNode * __ptr64> 444 Unknown
lm
列出。 - Thomas Weller