Hi all!
I'm trying to identify a memory leak in a WPF application. The application suffers from high memory consumption and occasionally throws OutOfMemoryExceptions. However, the application does not always show these behaviors.
I was able to create a memory dump on a machine when the memory load was very high by using procdump.exe. The dump file's size is about 1.7 GB. I then tried to analyze it using WinDbg. Using!address -summary gives the following output and shows about 1.7 GB of private bytes (MEM_COMMIT):
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal<unclassified> 2430 623a1000 ( 1.535 Gb) 82.09% 76.74% Image 1583 13dc5000 ( 317.770 Mb) 16.60% 15.52% Free 516 8583000 ( 133.512 Mb) 6.52% Stack 111 18a5000 ( 24.645 Mb) 1.29% 1.20% TEB 37 25000 ( 148.000 kb) 0.01% 0.01% NlsTables 1 23000 ( 140.000 kb) 0.01% 0.01% ActivationContextData 11 14000 ( 80.000 kb) 0.00% 0.00% CsrSharedMemory 1 5000 ( 20.000 kb) 0.00% 0.00% PEB 1 1000 ( 4.000 kb) 0.00% 0.00% --- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal MEM_PRIVATE 2144 58bbb000 ( 1.386 Gb) 74.16% 69.32% MEM_IMAGE 1929 163bf000 ( 355.746 Mb) 18.58% 17.37% MEM_MAPPED 102 8af3000 ( 138.949 Mb) 7.26% 6.78% --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal MEM_COMMIT 3206 6da16000 ( 1.713 Gb) 91.62% 85.65% MEM_RESERVE 969 a057000 ( 160.340 Mb) 8.38% 7.83% MEM_FREE 516 8583000 ( 133.512 Mb) 6.52% --- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal PAGE_READWRITE 1605 50166000 ( 1.251 Gb) 66.93% 62.57% PAGE_EXECUTE_READ 271 11e83000 ( 286.512 Mb) 14.97% 13.99% PAGE_READONLY 623 7335000 ( 115.207 Mb) 6.02% 5.63% PAGE_READWRITE|PAGE_WRITECOMBINE 8 2710000 ( 39.063 Mb) 2.04% 1.91% PAGE_WRITECOPY 328 15bf000 ( 21.746 Mb) 1.14% 1.06% PAGE_EXECUTE_READWRITE 210 7ef000 ( 7.934 Mb) 0.41% 0.39% PAGE_EXECUTE_WRITECOPY 75 181000 ( 1.504 Mb) 0.08% 0.07% PAGE_READWRITE|PAGE_GUARD 82 b5000 ( 724.000 kb) 0.04% 0.03% <unknown> 4 4000 ( 16.000 kb) 0.00% 0.00% --- Largest Region by Usage ----------- Base Address -------- Region Size ---------- <unclassified> 44150000 22c0000 ( 34.750 Mb) Image 802000 243f000 ( 36.246 Mb) Free 7a740000 d80000 ( 13.500 Mb) Stack 6e10000 fd000 (1012.000 kb) TEB 7eed9000 1000 ( 4.000 kb) NlsTables 7efb0000 23000 ( 140.000 kb) ActivationContextData 50000 4000 ( 16.000 kb) CsrSharedMemory 7efe0000 5000 ( 20.000 kb) PEB 7efde000 1000 ( 4.000 kb)
Using !eeheap -gc shows the following result:
Number of GC Heaps: 1 generation 0 starts at 0x78747eb4 generation 1 starts at 0x78741000 generation 2 starts at 0x04781000 ephemeral segment allocation context: none segment begin allocated size 04780000 04781000 0577fca4 0xffeca4(16772260) ... 78740000 78741000 78841ff4 0x100ff4(1052660) Large object heap starts at 0x05781000 segment begin allocated size 05780000 05781000 06755a58 0xfd4a58(16599640) ... 52f80000 52f81000 53e07308 0xe86308(15229704) Total Size: Size: 0x279b9d7c (664509820) bytes. ------------------------------ GC Heap Size: Size: 0x279b9d7c (664509820) bytes.
As you can see the managed heap only has about 633 MB so there is a gap of around 1 GB between the managed heap and the private bytes - which in my opinion points to an unmanaged leak. Since we are using P/Invoke and COM interop in the application that might
be a good starting point. I was trying !heap -s, which shows the following output:
LFH Key : 0x2c96c29b Termination on corruption : ENABLED Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap ----------------------------------------------------------------------------- Virtual block: 15f20000 - 15f20000 (size 00000000) ... Virtual block: 69cd0000 - 69cd0000 (size 00000000) 02de0000 00000002 81152 66472 81152 738 397 9 56 1 LFH 00720000 00001002 1088 136 1088 16 9 2 0 0 LFH 00470000 00041002 256 4 256 2 1 1 0 0 Virtual block: 1b150000 - 1b150000 (size 00000000) ... Virtual block: 6b0d0000 - 6b0d0000 (size 00000000) 00180000 00001002 15424 11932 15424 61 163 5 44 0 LFH 00030000 00001002 1088 136 1088 16 9 2 0 0 LFH 00680000 00041002 256 4 256 0 1 1 0 0 045e0000 00001002 15424 14092 15424 23 29 5 0 0 LFH 00410000 00041002 1280 308 1280 1 2 2 0 0 LFH 04590000 00041002 256 120 256 1 19 1 0 0 LFH 06820000 00001002 256 108 256 6 4 1 0 0 LFH 09d80000 00001002 256 120 256 1 12 1 0 0 LFH 09c80000 00001002 256 96 256 5 6 1 0 0 LFH 09d10000 00011002 256 12 256 9 5 1 0 0 09f50000 00001002 256 4 256 1 2 1 0 0 0a990000 00001002 3136 2444 3136 819 78 3 0 0 LFH External fragmentation 33 % (78 free blocks) 0a8d0000 00001002 15424 11792 15424 3620 140 5 0 0 LFH External fragmentation 30 % (140 free blocks) 0ad20000 00001002 256 156 256 81 2 1 0 0 0abe0000 00001002 256 104 256 11 6 1 0 0 LFH 125a0000 00001002 3136 2936 3136 520 102 3 0 0 LFH External fragmentation 17 % (102 free blocks) 12330000 00001002 64 8 64 4 6 1 0 0 0cda0000 00001002 64 12 64 3 1 1 0 0 280e0000 00001003 256 76 256 49 13 1 0 bad 28e10000 00001003 256 4 256 2 1 1 0 bad 29900000 00001003 256 4 256 2 1 1 0 bad 40190000 00001003 256 4 256 2 1 1 0 bad 10dd0000 00001003 256 4 256 2 1 1 0 bad 5b0d0000 00001003 1280 648 1280 627 18 2 0 bad 5bc70000 00001003 256 4 256 2 1 1 0 bad 30e90000 00001003 256 4 256 2 1 1 0 bad 5be60000 00001003 256 4 256 2 1 1 0 bad 30e50000 00001003 256 4 256 2 1 1 0 bad 5b330000 00001002 64 8 64 5 1 1 0 0 5b450000 00001002 64 12 64 3 2 1 0 0 5b5a0000 00001002 64 12 64 1 4 1 0 0 5db00000 00001002 3136 1572 3136 6 13 3 0 0 LFH 610a0000 00001002 256 4 256 2 1 1 0 0 612d0000 00001003 64 8 64 2 2 1 0 bad -----------------------------------------------------------------------------
If I sum up the sizes (committed) of all those heaps the sum is far below 1 GB. Where to go from here? Which steps should I take to identify the source of memory issue?
Thanks,
Markus