三个关键命令找出ASP.NET程序内存分片的原因
2007-10-26 11:20 lixiong 阅读(6014) 评论(18) 编辑 收藏 举报最近一位朋友的ASP.NET程序怀疑有内存泄露问题。几个简单的页面,起来运行几分钟后,虚拟内存就到600多MB。从性能监视上看,private bytes只有200多MB。
这样的问题从经验上来说,十有八九都是内存碎片了。ASP.NET程序发生内存碎片的原因比较多,我常见的有:
1. Web.config中的debug=true,导致batch compilation=false,使得每一个ASPX页面都生成一个临时assembly。当页面比较多的时候,大量的assembly导致内存泄露。
2. 程序中误用了XmlSerializer。频繁的XML序列化导致大量的动态assembly
3. 程序中有大量的blocking IO操作,而且IO buffer没有及时释放。比如程序中有大量的Web Service调用,但是对方web service返回比较慢,使得调用程序中用来接收web service结果的小块buffer大量堆积,导致内存泄露
下面是我拿到dump后的分析步骤。对于managed程序,找出问题的大致线索还是挺简单的。
(随便无耻地推销下,《Windows高效排错》书中对这样的问题有更多的讨论。包括更多的案例和命令解释。该书最初的PDF草稿在http://www.cnblogs.com/lixiong/archive/2006/08/16/475520.html。如果有朋友从这个PDF中找到过排错的灵感,麻烦也帮忙无耻推销下。)
首先是看看CLR的版本了。这个直接看mscorwks文件或者mscorsrv文件。如果文件版本比较低,后面的就没必要仔细看了,升级CLR补丁后再说。
0:000> lmvm mscorwks
start end module name
79e70000 7a3d6000 mscorwks (deferred)
Image path: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Image name: mscorwks.dll
Timestamp: Fri Apr 13 15:15:54 2007 (461F2E2A)
CheckSum: 00564CA8
ImageSize: 00566000
File version: 2.0.50727.832
Product version: 2.0.50727.832
File flags: 0 (Mask 3F)
File OS: 4 Unknown Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0409.04b0
CompanyName: Microsoft Corporation
ProductName: Microsoft® .NET Framework
InternalName: mscorwks.dll
OriginalFilename: mscorwks.dll
ProductVersion: 2.0.50727.832
FileVersion: 2.0.50727.832 (QFE.050727-8300)
FileDescription: Microsoft .NET Runtime Common Language Runtime - WorkStation
LegalCopyright: © Microsoft Corporation. All rights reserved.
Comments: Flavor=Retail
恩,版本还是比较新的。既然是内存问题,先看GC中有多少object,占用了多少内存
0:000> !eeheap -gc
Number of GC Heaps: 4
------------------------------
Heap 0 (000f3f10)
generation 0 starts at 0x02fad2fc
generation 1 starts at 0x02f83ff8
generation 2 starts at 0x02f00038
ephemeral segment allocation context: none
segment begin allocated size
00109198 7a72c42c 7a74d308 0x00020edc(134876)
000fdfb0 790d5588 790f4b38 0x0001f5b0(128432)
02f00000 02f00038 03081450 0x00181418(1578008)
Large object heap starts at 0x12f00038
segment begin allocated size
12f00000 12f00038 131b00a0 0x002b0068(2818152)
Heap Size 0x47190c(4659468)
------------------------------
Heap 1 (000f50a0)
generation 0 starts at 0x06f5b110
generation 1 starts at 0x06f5acf8
generation 2 starts at 0x06f00038
ephemeral segment allocation context: none
segment begin allocated size
06f00000 06f00038 06ff511c 0x000f50e4(1003748)
Large object heap starts at 0x14f00038
segment begin allocated size
14f00000 14f00038 14f00048 0x00000010(16)
Heap Size 0xf50f4(1003764)
------------------------------
Heap 2 (000f68a0)
generation 0 starts at 0x0af78634
generation 1 starts at 0x0af09d40
generation 2 starts at 0x0af00038
ephemeral segment allocation context: none
segment begin allocated size
0af00000 0af00038 0af92a0c 0x000929d4(600532)
Large object heap starts at 0x16f00038
segment begin allocated size
16f00000 16f00038 16f00048 0x00000010(16)
Heap Size 0x929e4(600548)
------------------------------
Heap 3 (000f7bc8)
generation 0 starts at 0x0ef7b270
generation 1 starts at 0x0ef7b264
generation 2 starts at 0x0ef00038
ephemeral segment allocation context: none
segment begin allocated size
0ef00000 0ef00038 0ef7d27c 0x0007d244(512580)
Large object heap starts at 0x18f00038
segment begin allocated size
18f00000 18f00038 18f00048 0x00000010(16)
Heap Size 0x7d254(512596)
------------------------------
GC Heap Size 0x676638(6776376)
内存占用只有6M,显然不是CLR object导致的问题。那看来真的就是内存碎片了。于是先看看程序中有多少DLL:
0:000> lmf
start end module name
00900000 00bc5000 xpsp2res C:\WINDOWS\system32\xpsp2res.dll
01000000 01005000 w3wp c:\WINDOWS\system32\inetsrv\w3wp.exe
1b740000 1b748000 App_global_asax_incckcvw C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\App_global.asax.incckcvw.dll
1b770000 1b790000 Boke_WebRoot_Admin C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\assembly\dl3\0854db20\0aaa279d_a314c801\Boke.WebRoot.Admin.DLL
1b7e0000 1b820000 log4net C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\assembly\dl3\8af1019b\00a071ef_de00c801\log4net.DLL
1bb00000 1bb0e000 App_Web_fsrghzyk C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\App_Web_fsrghzyk.dll
1bb20000 1bb30000 AspNetPager C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\assembly\dl3\53ce5ce1\00a071ef_de00c801\AspNetPager.DLL
1bb30000 1bb3c000 App_Web_qenznn_e C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b972f933\24c4c459\App_Web_qenznn_e.dll
1bb60000 1bb70000 UDMap D:\webfolder\dvdvAdmin\bin\Map.dll
50210000 5025c000 SMDiagnostics_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\SMDiagnostics\da4366daf8361c62ed3fcec4c55fa9ca\SMDiagnostics.ni.dll
50270000 50368000 System_IdentityModel_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.IdentityModel\bc31a40dee949687576d5395efcab6a0\System.IdentityModel.ni.dll
504e0000 50728000 System_Runtime_Serialization_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Runtime.Seri#\c861896fa11d6eef9fed23cff7b77b01\System.Runtime.Serialization.ni.dll
507a0000 5185e000 System_ServiceModel_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.ServiceModel\719a7cce9b36b780b3edd9869ceb2537\System.ServiceModel.ni.dll
5a300000 5a307000 w3tp c:\WINDOWS\system32\inetsrv\w3tp.dll
5a320000 5a332000 w3isapi c:\WINDOWS\system32\inetsrv\w3isapi.dll
5a360000 5a36d000 w3dt c:\WINDOWS\system32\inetsrv\w3dt.dll
5a390000 5a3e8000 w3core c:\WINDOWS\system32\inetsrv\w3core.dll
5a3f0000 5a3f6000 w3comlog c:\WINDOWS\system32\inetsrv\w3comlog.dll
5a400000 5a408000 w3cache c:\WINDOWS\system32\inetsrv\w3cache.dll
5a420000 5a431000 iismap C:\WINDOWS\system32\iismap.dll
5b640000 5b658000 strmfilt C:\WINDOWS\system32\strmfilt.dll
5e620000 5e6da000 Microsoft_JScript C:\WINDOWS\assembly\GAC_MSIL\Microsoft.JScript\8.0.0.0__b03f5f7f11d50a3a\Microsoft.JScript.dll
5f270000 5f2ca000 hnetcfg C:\WINDOWS\system32\hnetcfg.dll
60060000 60066000 aspnet_filter C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll
60070000 60075000 aspnet_isapi \\?\c:\WINDOWS\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll
608f0000 60901000 admwprox C:\WINDOWS\system32\admwprox.dll
60ba0000 60bb1000 wamreg c:\WINDOWS\system32\inetsrv\wamreg.dll
62da0000 62da7000 lonsint c:\WINDOWS\system32\inetsrv\lonsint.dll
637a0000 63d02000 System_Xml_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Xml\e342cc4334d3ab13ce752de73164c01b\System.Xml.ni.dll
64700000 6472d000 iisutil c:\WINDOWS\system32\inetsrv\iisutil.dll
647b0000 647d7000 iisrtl C:\WINDOWS\system32\iisrtl.dll
64890000 6498a000 System_Configuration_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Configuration\edc1f15b90b2c6a4dc59b305f14bb98d\System.Configuration.ni.dll
64e70000 6513c000 System_Data C:\WINDOWS\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll
65140000 657a6000 System_Data_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Data\42481d9f835b4b6c150c50d2642781b9\System.Data.ni.dll
65f20000 66ac6000 System_Web_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Web\83c662f1a20af1b2deea3f9a040ccbd6\System.Web.ni.dll
67150000 67159000 httpapi C:\WINDOWS\system32\httpapi.dll
68000000 68035000 rsaenh C:\WINDOWS\system32\rsaenh.dll
685b0000 685ba000 gzip C:\WINDOWS\system32\inetsrv\gzip.dll
695a0000 697da000 System_Web_Mobile_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Web.Mobile\e7d2fee1612b52a914d8d253d5e49a7c\System.Web.Mobile.ni.dll
69890000 698d0000 System_Web_RegularExpressions_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Web.RegularE#\1fa927a42b36176da2cdc193f0435950\System.Web.RegularExpressions.ni.dll
6a2a0000 6a307000 webengine \\?\c:\WINDOWS\microsoft.net\framework\v2.0.50727\webengine.dll
6d0f0000 6d110000 iisres c:\WINDOWS\system32\inetsrv\iisres.dll
71640000 7180d000 acgenral C:\WINDOWS\AppPatch\acgenral.dll
71ae0000 71ae8000 wshtcpip C:\WINDOWS\system32\wshtcpip.dll
71af0000 71b12000 shimeng C:\WINDOWS\system32\shimeng.dll
71b20000 71b61000 mswsock C:\WINDOWS\system32\mswsock.dll
71b70000 71ba6000 uxtheme C:\WINDOWS\system32\uxtheme.dll
71bb0000 71bb9000 wsock32 C:\WINDOWS\system32\wsock32.dll
71bd0000 71be1000 mpr C:\WINDOWS\system32\mpr.dll
71bf0000 71bf8000 ws2help C:\WINDOWS\system32\ws2help.dll
71c00000 71c17000 ws2_32 C:\WINDOWS\system32\ws2_32.dll
71c40000 71c97000 netapi32 C:\WINDOWS\system32\netapi32.dll
745e0000 7489e000 msi C:\WINDOWS\system32\msi.dll
75490000 754f5000 usp10 C:\WINDOWS\system32\usp10.dll
75e60000 75e87000 apphelp C:\WINDOWS\system32\apphelp.dll
76190000 761a2000 msasn1 C:\WINDOWS\system32\msasn1.dll
761b0000 76243000 crypt32 C:\WINDOWS\system32\crypt32.dll
76290000 762ad000 imm32 C:\WINDOWS\system32\imm32.dll
76920000 769e2000 userenv C:\WINDOWS\system32\userenv.dll
76aa0000 76acd000 winmm C:\WINDOWS\system32\winmm.dll
76b70000 76b7b000 psapi C:\WINDOWS\system32\psapi.dll
76c90000 76cb7000 msv1_0 C:\WINDOWS\system32\msv1_0.dll
76cf0000 76d0a000 iphlpapi C:\WINDOWS\system32\iphlpapi.dll
76e30000 76e3c000 rtutils C:\WINDOWS\system32\rtutils.dll
76e40000 76e52000 rasman C:\WINDOWS\system32\rasman.dll
76e60000 76e8f000 tapi32 C:\WINDOWS\system32\tapi32.dll
76e90000 76ecf000 rasapi32 C:\WINDOWS\system32\rasapi32.dll
76ed0000 76efa000 dnsapi C:\WINDOWS\system32\dnsapi.dll
76f10000 76f3e000 wldap32 C:\WINDOWS\system32\wldap32.dll
76f50000 76f63000 secur32 C:\WINDOWS\system32\secur32.dll
76f70000 76f77000 winrnr C:\WINDOWS\system32\winrnr.dll
76f80000 76f85000 rasadhlp C:\WINDOWS\system32\rasadhlp.dll
77010000 770d6000 comres C:\WINDOWS\system32\comres.dll
77380000 77411000 user32 C:\WINDOWS\system32\user32.dll
77420000 77523000 comctl32 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.3790.3959_x-ww_D8713E55\comctl32.dll
77670000 777a9000 ole32 C:\WINDOWS\system32\ole32.dll
777b0000 77833000 clbcatq C:\WINDOWS\system32\clbcatq.dll
77b70000 77b84000 msacm32 C:\WINDOWS\system32\msacm32.dll
77b90000 77b98000 version C:\WINDOWS\system32\version.dll
77ba0000 77bfa000 msvcrt C:\WINDOWS\system32\msvcrt.dll
77c00000 77c48000 gdi32 C:\WINDOWS\system32\gdi32.dll
77c50000 77cef000 rpcrt4 C:\WINDOWS\system32\rpcrt4.dll
77d00000 77d8b000 oleaut32 C:\WINDOWS\system32\oleaut32.dll
77da0000 77df2000 shlwapi C:\WINDOWS\system32\shlwapi.dll
77e00000 77e21000 ntmarta C:\WINDOWS\system32\ntmarta.dll
77e40000 77f42000 kernel32 C:\WINDOWS\system32\kernel32.dll
77f50000 77feb000 advapi32 C:\WINDOWS\system32\advapi32.dll
78130000 781cb000 msvcr80 C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0DE06ACD\msvcr80.dll
79000000 79045000 mscoree C:\WINDOWS\system32\mscoree.dll
79060000 790b3000 mscorjit C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll
790c0000 79b90000 mscorlib_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\56cbcbd518a77421a852a37b61624936\mscorlib.ni.dll
79e70000 7a3d6000 mscorwks C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
7a440000 7ac06000 System_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System\19aba12bb5350aa99107e93bafbb4f51\System.ni.dll
7ade0000 7af6c000 System_Drawing_ni C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System.Drawing\e3104e1713757f14b54b7835be2a0e26\System.Drawing.ni.dll
7c800000 7c8c0000 ntdll C:\WINDOWS\system32\ntdll.dll
7c8d0000 7d0ce000 shell32 C:\WINDOWS\system32\shell32.dll
7e020000 7e02f000 samlib C:\WINDOWS\system32\samlib.dll
7f000000 7f009000 lpk C:\WINDOWS\system32\lpk.dll
非常普通。也就这点DLL,根本没有导致内存碎片的潜力呀!不死心,看看是不是有很多线程被block住了。要是有个几百个线程,嘿嘿
0:000> ~
. 0 Id: 694.540 Suspend: 1 Teb: 7ffdd000 Unfrozen
1 Id: 694.12a0 Suspend: 1 Teb: 7ffdb000 Unfrozen
2 Id: 694.1040 Suspend: 1 Teb: 7ffda000 Unfrozen
3 Id: 694.11f0 Suspend: 1 Teb: 7ffd9000 Unfrozen
4 Id: 694.13d0 Suspend: 1 Teb: 7ffd7000 Unfrozen
5 Id: 694.1338 Suspend: 1 Teb: 7ffd6000 Unfrozen
6 Id: 694.10e4 Suspend: 1 Teb: 7ffd5000 Unfrozen
7 Id: 694.e4c Suspend: 1 Teb: 7ffd4000 Unfrozen
8 Id: 694.10a8 Suspend: 1 Teb: 7ffd3000 Unfrozen
9 Id: 694.1144 Suspend: 1 Teb: 7ff9f000 Unfrozen
10 Id: 694.1340 Suspend: 1 Teb: 7ff9e000 Unfrozen
11 Id: 694.1484 Suspend: 1 Teb: 7ff9d000 Unfrozen
12 Id: 694.1170 Suspend: 1 Teb: 7ff9c000 Unfrozen
13 Id: 694.11d8 Suspend: 1 Teb: 7ff9b000 Unfrozen
14 Id: 694.1768 Suspend: 1 Teb: 7ff9a000 Unfrozen
15 Id: 694.173c Suspend: 1 Teb: 7ff99000 Unfrozen
16 Id: 694.a80 Suspend: 1 Teb: 7ff98000 Unfrozen
17 Id: 694.500 Suspend: 1 Teb: 7ff97000 Unfrozen
18 Id: 694.1194 Suspend: 1 Teb: 7ff96000 Unfrozen
19 Id: 694.16c8 Suspend: 1 Teb: 7ff95000 Unfrozen
20 Id: 694.162c Suspend: 1 Teb: 7ff94000 Unfrozen
21 Id: 694.a8c Suspend: 1 Teb: 7ff93000 Unfrozen
22 Id: 694.ad4 Suspend: 1 Teb: 7ff92000 Unfrozen
23 Id: 694.1098 Suspend: 1 Teb: 7ff2f000 Unfrozen
24 Id: 694.b08 Suspend: 1 Teb: 7ff2e000 Unfrozen
25 Id: 694.19c Suspend: 1 Teb: 7ff90000 Unfrozen
26 Id: 694.fcc Suspend: 1 Teb: 7ff2d000 Unfrozen
27 Id: 694.764 Suspend: 1 Teb: 7ff91000 Unfrozen
28 Id: 694.1334 Suspend: 1 Teb: 7ff2b000 Unfrozen
。。。线程也这么少,怎么办
还是不死心。从上面的DLL看到,程序中的模块要么系统的,要么CLR的,没有COM/COM+,问题应该还是在CLR相关的东西上。于是用!eeheap –loader看看loader heap的大小:
0:000> !eeheap -loader
Loader Heap:
--------------------------------------
System Domain: 7a38f918
LowFrequencyHeap: Size: 0x0(0)bytes.
HighFrequencyHeap: 02e72000(8000:1000) Size: 0x1000(4096)bytes.
StubHeap: 02e7a000(2000:2000) 1b5b0000(10000:4000) Size: 0x6000(24576)bytes.
Virtual Call Stub Heap:
IndcellHeap: Size: 0x0(0)bytes.
LookupHeap: Size: 0x0(0)bytes.
ResolveHeap: Size: 0x0(0)bytes.
DispatchHeap: Size: 0x0(0)bytes.
CacheEntryHeap: Size: 0x0(0)bytes.
Total size: 0x7000(28672)bytes
--------------------------------------
Shared Domain: 7a38fef0
LowFrequencyHeap: 02ea0000(2000:1000) 1b6d0000(10000:d000) Size: 0xe000(57344)bytes.
Wasted: 0x1000(4096)bytes.
HighFrequencyHeap: 02ea2000(8000:5000) Size: 0x5000(20480)bytes.
StubHeap: 02eaa000(2000:1000) 1bc80000(10000:1000) Size: 0x2000(8192)bytes.
Wasted: 0x1000(4096)bytes.
Virtual Call Stub Heap:
IndcellHeap: 02eb0000(2000:1000) Size: 0x1000(4096)bytes.
LookupHeap: 02eb5000(2000:1000) Size: 0x1000(4096)bytes.
ResolveHeap: 02ebb000(5000:5000) 1bc10000(10000:2000) Size: 0x7000(28672)bytes.
DispatchHeap: 02eb7000(4000:3000) Size: 0x3000(12288)bytes.
CacheEntryHeap: 02eb2000(3000:1000) Size: 0x1000(4096)bytes.
Total size: 0x21000(135168)bytes
--------------------------------------
Domain 1: ded80
LowFrequencyHeap: 02e80000(2000:1000) Size: 0x1000(4096)bytes.
HighFrequencyHeap: 02e82000(8000:4000) Size: 0x4000(16384)bytes.
StubHeap: Size: 0x0(0)bytes.
Virtual Call Stub Heap:
IndcellHeap: Size: 0x0(0)bytes.
LookupHeap: Size: 0x0(0)bytes.
ResolveHeap: Size: 0x0(0)bytes.
DispatchHeap: Size: 0x0(0)bytes.
CacheEntryHeap: Size: 0x0(0)bytes.
Total size: 0x5000(20480)bytes
--------------------------------------
Domain 2: 113b60
LowFrequencyHeap: 1b550000(2000:2000) 1b760000(10000:f000) 1b830000(10000:10000) 1bcd0000(10000:f000) 1c150000(10000:10000) 1c260000(10000:10000) 1c300000(10000:10000) 1c380000(10000:10000) 1c430000(10000:10000) 1c510000(10000:10000) 1c5c0000(10000:10000) 1c6b0000(10000:10000) 1c750000(10000:10000) 1c800000(10000:f000) 1c8b0000(10000:f000) 1c920000(10000:10000) ……
1db30000(10000:f000) 1dbc0000(10000:f000) 1dca0000(10000:f000) 1dd50000(10000:10000) 1de00000(10000:10000) 1de90000(10000:10000) 1df40000(10000:10000) 1dfb0000(10000:10000) 1df90000(10000:f000) 1e0e0000(10000:f000) 1e180000(10000:10000) 1e230000(10000:10000) 1e2d0000(10000:10000) 1e370000(10000:10000) 1e420000(10000:f000) 1e4b0000(10000:f000) 1e550000(10000:f000) 1e600000(10000:10000) 1e6b0000(10000:10000) 1e740000(10000:10000) 1e7f0000(10000:10000) 1e8e0000(10000:10000) 1eb60000(10000:f000) 1ec10000(10000:f000) 1ed30000(10000:10000) 1eda0000(10000:10000) 1ee40000(10000:c000) Size: 0x447000(4485120)bytes.
Wasted: 0x17000(94208)bytes.
HighFrequencyHeap: 1b552000(8000:8000) 1b820000(10000:f000) 1bb80000(10000:10000) 1c120000(10000:10000) 1c230000(10000:f000) 1c2d0000(10000:10000) 1c390000(10000:10000) 1c460000(10000:10000) 1c570000(10000:10000) 1c610000(10000:10000) 1c720000(10000:f000) 1c7d0000(10000:10000) ……
1dd20000(10000:10000) 1ddf0000(10000:10000) 1dea0000(10000:10000) 1df20000(10000:f000) 1df30000(10000:10000) 1e080000(10000:10000) 1e150000(10000:10000) 1e220000(10000:10000) 1e2e0000(10000:10000) 1e3b0000(10000:f000) 1e450000(10000:10000) 1e500000(10000:10000) 1e5d0000(10000:10000) 1e6a0000(10000:10000) 1e750000(10000:10000) 1e860000(10000:f000) 1e910000(10000:10000) 1ebb0000(10000:10000) 1ec80000(10000:10000) 1ed90000(10000:10000) 1ee50000(10000:9000) Size: 0x3b8000(3899392)bytes.
Wasted: 0x9000(36864)bytes.
StubHeap: 1b55a000(2000:1000) Size: 0x1000(4096)bytes.
Virtual Call Stub Heap:
IndcellHeap: 1b5a0000(3000:1000) Size: 0x1000(4096)bytes.
LookupHeap: 1b5a6000(3000:1000) Size: 0x1000(4096)bytes.
ResolveHeap: 1b5ac000(4000:1000) Size: 0x1000(4096)bytes.
DispatchHeap: 1b5a9000(3000:1000) Size: 0x1000(4096)bytes.
CacheEntryHeap: 1b5a3000(3000:1000) Size: 0x1000(4096)bytes.
Total size: 0x804000(8404992)bytes
--------------------------------------
Jit code heap:
LoaderCodeHeap: 1ee10000(10000:c000) Size: 0xc000(49152)bytes.
LoaderCodeHeap: 1ed60000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1ebe0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1e8d0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1e7a0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1e690000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1e5a0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1e4a0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1e3a0000(10000:10000) Size: 0x10000(65536)bytes.
……
LoaderCodeHeap: 1cb70000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1ca50000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c980000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c870000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c780000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c640000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c540000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c400000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c330000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1c1c0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1bce0000(10000:10000) Size: 0x10000(65536)bytes.
LoaderCodeHeap: 1bc70000(10000:1000) Size: 0x1000(4096)bytes.
HostCodeHeap: 1bc60000 Size: 0xa000(40960)bytes.
LoaderCodeHeap: 1b7d0000(10000:10000) Size: 0x10000(65536)bytes.
Total size: 0x2d7000(2977792)bytes
--------------------------------------
Module Thunk heaps:
Module 50224000: Size: 0x0(0)bytes.
Module 505c4000: Size: 0x0(0)bytes.
Module 648ec000: Size: 0x0(0)bytes.
Module 6638c000: Size: 0x0(0)bytes.
Module 7a71e000: Size: 0x0(0)bytes.
Module 502c2000: Size: 0x0(0)bytes.
Module 790c2000: Size: 0x0(0)bytes.
Module 02ea2380: Size: 0x0(0)bytes.
Module 02ea2010: Size: 0x0(0)bytes.
……
Module 1ed9705c: Size: 0x0(0)bytes.
Module 1ed9a884: Size: 0x0(0)bytes.
Module 1ed9e0ac: Size: 0x0(0)bytes.
Module 1ee51944: Size: 0x0(0)bytes.
Module 1ee5516c: Size: 0x0(0)bytes.
Total size: 0x0(0)bytes
--------------------------------------
Module Lookup Table heaps:
Module 50224000: Size: 0x0(0)bytes.
Module 505c4000: Size: 0x0(0)bytes.
Module 648ec000: Size: 0x0(0)bytes.
Module 6638c000: Size: 0x0(0)bytes.
Module 7a71e000: Size: 0x0(0)bytes.
Module 502c2000: Size: 0x0(0)bytes.
Module 790c2000: Size: 0x0(0)bytes.
Module 02ea2380: Size: 0x0(0)bytes.
Module 02ea2010: Size: 0x0(0)bytes.
Module 69670000: Size: 0x0(0)bytes.
……
Module 639ea000: Size: 0x0(0)bytes.
Module 50d5a000: Size: 0x0(0)bytes.
Module 653b4000: Size: 0x0(0)bytes.
Module 02ea27cc: Size: 0x0(0)bytes.
Module 1ed9705c: Size: 0x0(0)bytes.
Module 1ed9a884: Size: 0x0(0)bytes.
Module 1ed9e0ac: Size: 0x0(0)bytes.
Module 1ee51944: Size: 0x0(0)bytes.
Module 1ee5516c: Size: 0x0(0)bytes.
Total size: 0x0(0)bytes
--------------------------------------
Total LoaderHeap size: 0xb08000(11567104)bytes
=======================================
上面只是!eeheap –loader输出的5%左右。从上面的输出来看,loader heap占用了11MB的内存。这个数字没问题,问题在于这个module list上面。这里成千上万的module,势必导致内存碎片。
前面lmvm命令可以检查加载的module。但是lmvm命令工作方式是Win32层面的。如果DLL通过LoadLibrary起来的,这个命令能看到。但是CLR的动态DLL,除了使用LoadLibrary外,CLR还可以直接用MapViewOfFile的方法直接把DLL弄到内存中操作。这种情况lmvm就没把法了。所以需要用!eeheap –loader从CLR层面检查。
除了!eeheap外,用!dumpdomain命令,也可以从CLR层面列举出所有的assembly,包括动态的和静态的。
找到内存碎片的原因后,接下来就是分析这些碎片的来源了。既然这里是module,那随便挑一个,用!dumpmodule检查详细信息:
0:000> !dumpmodule -mt 1ee5516c
Name: cplxobsw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Attributes: PEFile
Assembly: 1e929530
LoaderHeap: 00000000
TypeDefToMethodTableMap: 1ee47f18
TypeRefToMethodTableMap: 1ee47fe4
MethodDefToDescMap: 1ee48058
FieldDefToDescMap: 1ee484f4
MemberRefToDescMap: 1ee486e8
FileReferencesMap: 1ee488a4
AssemblyReferencesMap: 1ee488a8
MetaData start address: 1ee8be8c (49668 bytes)
Types defined in this module
MT TypeDef Name
------------------------------------------------------------------------------
1ee57e5c 0x02000002 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap
1ee587ac 0x02000003 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderI_UAC_WSSoap
1ee55844 0x02000004 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializer1
1ee56fac 0x02000005 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer
1ee5745c 0x02000006 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer1
1ee579d4 0x02000007 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer2
1ee575ec 0x02000008 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer3
1ee55e7c 0x02000009 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer4
1ee559cc 0x0200000a Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer5
1ee55b5c 0x0200000b Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer6
1ee57a9c 0x0200000c Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer7
1ee55db4 0x0200000d Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer8
1ee56714 0x0200000e Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer9
1ee5777c 0x0200000f Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer10
1ee57524 0x02000010 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer11
1ee56d54 0x02000011 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer12
1ee57844 0x02000012 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer13
1ee568a4 0x02000013 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer14
1ee576b4 0x02000014 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer15
1ee55a94 0x02000015 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer16
1ee55cec 0x02000016 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer17
1ee57204 0x02000017 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer18
1ee5619c 0x02000018 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer19
1ee5632c 0x02000019 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer20
1ee55f44 0x0200001a Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer21
1ee572cc 0x0200001b Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer22
1ee57c2c 0x0200001c Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer23
1ee55c24 0x0200001d Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer24
1ee56c8c 0x0200001e Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer25
1ee567dc 0x0200001f Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer26
1ee56e1c 0x02000020 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer27
1ee56584 0x02000021 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer28
1ee56a34 0x02000022 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer29
1ee5713c 0x02000023 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer30
1ee5600c 0x02000024 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer31
1ee57074 0x02000025 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer32
1ee560d4 0x02000026 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer33
1ee564bc 0x02000027 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer34
1ee5696c 0x02000028 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer35
1ee57394 0x02000029 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer36
1ee56ee4 0x0200002a Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer37
1ee563f4 0x0200002b Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer38
1ee56264 0x0200002c Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer39
1ee56afc 0x0200002d Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer40
1ee56bc4 0x0200002e Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer41
1ee5790c 0x0200002f Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer42
1ee5664c 0x02000030 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer43
1ee57b64 0x02000031 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer44
1ee55904 0x02000032 Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer45
1ee5575c 0x02000033 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract
Types referenced in this module
MT TypeRef Name
------------------------------------------------------------------------------
63a191a4 0x01000001 System.Xml.Serialization.XmlSerializationWriter
63a18ac0 0x01000002 System.Xml.Serialization.XmlSerializationReader
63a19804 0x01000003 System.Xml.Serialization.XmlSerializer
63a19798 0x01000004 System.Xml.Serialization.XmlSerializerImplementation
1bb88e8c 0x01000005 t_UserInfo
639f2988 0x01000006 System.Xml.XmlReader
790fd8b4 0x01000007 System.Collections.Hashtable
790ffe7c 0x01000008 System.Type
790f9244 0x0100000e System.String
790fdb60 0x0100000f System.Int32
639f3758 0x01000010 System.Xml.XmlConvert
790f8a7c 0x01000014 System.Object
79103c00 0x01000019 System.Boolean
639f59e0 0x0100001a System.Xml.XmlQualifiedName
639fa358 0x0100001b System.Xml.XmlNameTable
上面的输入就非常明显了。程序明显是在做XmlSerialization。接下来看看是在Serialize什么类型的object,有了这个信息后,去看源代码就更有方向了.随便找一个method table来看:
0:000> !dumpmt -md 1ee57e5c
EEClass: 1ee4b428
Module: 1ee5516c
Name: Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap
mdToken: 02000002 (cplxobsw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)
BaseSize: 0x44
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 53
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
7934cdcc 79137ab8 PreJIT System.Object.ToString()
7934bba0 79137ac0 PreJIT System.Object.Equals(System.Object)
7934bb90 79137ad8 PreJIT System.Object.GetHashCode()
793424c0 79137ae0 PreJIT System.Object.Finalize()
1ee5802d 1ee57e38 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.InitCallbacks()
1ee57f61 1ee57cc0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write3_UserReg(System.Object[])
1ee57f65 1ee57cc8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write4_UserRegResponse(System.Object[])
1ee57f69 1ee57cd0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write5_UserRegSimple(System.Object[])
1ee57f6d 1ee57cd8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write6_UserRegSimpleResponse(System.Object[])
1ee57f71 1ee57ce0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write7_UserRegPhone(System.Object[])
1ee57f75 1ee57ce8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write8_UserRegPhoneResponse(System.Object[])
1ee57f79 1ee57cf0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write9_ModifyUserInfo(System.Object[])
1ee57f7d 1ee57cf8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write10_ModifyUserInfoResponse(System.Object[])
1ee57f81 1ee57d00 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write11_UserLogin(System.Object[])
1ee57f85 1ee57d08 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write12_UserLoginResponse(System.Object[])
1ee57f89 1ee57d10 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write13_UserLogout(System.Object[])
1ee57f8d 1ee57d18 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write14_UserLogoutResponse(System.Object[])
1ee19d80 1ee57d20 JIT Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write15_GetUserInfo(System.Object[])
1ee57f95 1ee57d28 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write16_GetUserInfoResponse(System.Object[])
1ee57f99 1ee57d30 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write17_FindUser(System.Object[])
1ee57f9d 1ee57d38 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write18_FindUserResponse(System.Object[])
1ee57fa1 1ee57d40 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write19_FindUserEx(System.Object[])
1ee57fa5 1ee57d48 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write20_FindUserExResponse(System.Object[])
1ee57fa9 1ee57d50 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write21_ModifyPassword(System.Object[])
1ee57fad 1ee57d58 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write22_ModifyPasswordResponse(System.Object[])
1ee57fb1 1ee57d60 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write23_ResetPassword(System.Object[])
1ee57fb5 1ee57d68 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write24_ResetPasswordResponse(System.Object[])
1ee57fb9 1ee57d70 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write25_ModifyPasswordPhone(System.Object[])
1ee57fbd 1ee57d78 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write26_ModifyPasswordPhoneResponse(System.Object[])
1ee57fc1 1ee57d80 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write27_CheckUserToken(System.Object[])
1ee57fc5 1ee57d88 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write28_CheckUserTokenResponse(System.Object[])
1ee57fc9 1ee57d90 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write29_SetUserStatus(System.Object[])
1ee57fcd 1ee57d98 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write30_SetUserStatusResponse(System.Object[])
1ee57fd1 1ee57da0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write31_ActivateUser(System.Object[])
1ee57fd5 1ee57da8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write32_ActivateUserResponse(System.Object[])
1ee57fd9 1ee57db0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write33_AppActivateUser(System.Object[])
1ee57fdd 1ee57db8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write34_AppActivateUserResponse(System.Object[])
1ee57ff1 1ee57dc0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write35_GetUserLoginHistory(System.Object[])
1ee57ff5 1ee57dc8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write36_GetUserLoginHistoryResponse(System.Object[])
1ee57ff9 1ee57dd0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write37_GetUnactiveUserNumber(System.Object[])
1ee57ffd 1ee57dd8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write38_GetUnactiveUserNumberResponse(System.Object[])
1ee58001 1ee57de0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write39_GetTtlUserNumber(System.Object[])
1ee58005 1ee57de8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write40_GetTtlUserNumberResponse(System.Object[])
1ee58009 1ee57df0 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write41_GetActiveUserNumber(System.Object[])
1ee5800d 1ee57df8 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write42_GetActiveUserNumberResponse(System.Object[])
1ee58011 1ee57e00 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write43_DailyRegisterCount(System.Object[])
1ee58015 1ee57e08 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write44_DailyRegisterCountResponse(System.Object[])
1ee58019 1ee57e10 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write45_GetDailyReport(System.Object[])
1ee5801d 1ee57e18 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write46_GetDailyReportResponse(System.Object[])
1ee58021 1ee57e20 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write47_Test(System.Object[])
1ee58025 1ee57e28 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write48_TestResponse(System.Object[])
1ee19eb8 1ee57e30 JIT Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap.Write2_t_UserInfo(System.String, System.String, t_UserInfo, Boolean, Boolean)
1ee58031 1ee57e40 NONE Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterI_UAC_WSSoap..ctor()
从上面的输出中,就能看到序列化类型的方法。有了这些方法,查找序列化的来源就容易多了。
有了这些信息后,开发人员很容易地定位到问题跟WCF调用相关。实现WCF的时候选择了XML序列化方法。在下面这个blog的评论中,有人批评WCF XML序列化会导致这样的问题:
http://blogs.msdn.com/tess/archive/2006/02/15/net-memory-leak-xmlserializing-your-way-to-a-memory-leak.aspx
这个问题在这里已经非常明显了。当然dump中还有其它可以挖掘的地方。比如用!dumpheap –stat看看CLR object的数量。用!dumpheap –mt寻找一些序列化object的地址,然后用!gcroot看看序列化object的引用关系。或者用!finalizequeue看看是否堆积了大量的object等待Dispose。由于篇幅的关系,这些细枝末节就不列举了。
总的说来,!eeheap –gc隔离问题到loader heap和dynamic module, !dumpmodule –mt找到引发序列化的类型,!dumpmt –md找出类型的详细信息。三个命令就可以隔离出问题。
该问题最后通过WCF object pool的方法缓存WCF client proxy,解决问题。