I'm trying to understand the memory usage of a program I maintain. I've realised that from a process dump I can use windbg to do "heap -a 0" to print every single allocation that my process hasn't yet deleted. Each allocation looks a bit like:
0000000006a905c0: 000a0 . 000a0 [07] - busy (68), tail fill - unable to read heap entry extra at 0000000006a90650
Where the 68 is what I malloced and 000a0 is how much memory is actually used (since there's a bit of overhead).
If I add all these allocations up for my program, I get 34Mb, however, this seems to bear little relationship to the memory summary in !address -summary which shows:
0:000> !address -summary
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 132 7ff`e905b000 ( 8.000 Tb) 100.00%
<unclassified> 1234 0`11025000 ( 272.145 Mb) 74.04% 0.00%
Image 430 0`03fe6000 ( 63.898 Mb) 17.38% 0.00%
Stack 93 0`01f00000 ( 31.000 Mb) 8.43% 0.00%
TEB 31 0`0003e000 ( 248.000 kb) 0.07% 0.00%
NlsTables 1 0`00024000 ( 144.000 kb) 0.04% 0.00%
ActivationContextData 22 0`0001e000 ( 120.000 kb) 0.03% 0.00%
CsrSharedMemory 1 0`00009000 ( 36.000 kb) 0.01% 0.00%
PEB 1 0`00001000 ( 4.000 kb) 0.00% 0.00%
--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE 1340 0`1167d000 ( 278.488 Mb) 75.76% 0.00%
MEM_IMAGE 430 0`03fe6000 ( 63.898 Mb) 17.38% 0.00%
MEM_MAPPED 43 0`01932000 ( 25.195 Mb) 6.85% 0.00%
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 132 7ff`e905b000 ( 8.000 Tb) 100.00%
MEM_RESERVE 631 0`0e970000 ( 233.438 Mb) 63.51% 0.00%
MEM_COMMIT 1182 0`08625000 ( 134.145 Mb) 36.49% 0.00%
--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READWRITE 788 0`04428000 ( 68.156 Mb) 18.54% 0.00%
PAGE_EXECUTE_READ 85 0`027b8000 ( 39.719 Mb) 10.81% 0.00%
PAGE_READONLY 225 0`01984000 ( 25.516 Mb) 6.94% 0.00%
PAGE_WRITECOPY 51 0`00081000 ( 516.000 kb) 0.14% 0.00%
PAGE_READWRITE|PAGE_GUARD 31 0`0003e000 ( 248.000 kb) 0.07% 0.00%
PAGE_EXECUTE_READWRITE 2 0`00002000 ( 8.000 kb) 0.00% 0.00%
--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free 1`80014000 7fd`cb33c000 ( 7.991 Tb)
<unclassified> 0`0eae9000 0`037d7000 ( 55.840 Mb)
Image 7ff`7f56e000 0`0062e000 ( 6.180 Mb)
Stack 0`04120000 0`000fc000 (1008.000 kb)
TEB 7ff`fff7c000 0`00002000 ( 8.000 kb)
NlsTables 7ff`fffb0000 0`00024000 ( 144.000 kb)
ActivationContextData 0`00130000 0`00005000 ( 20.000 kb)
CsrSharedMemory 0`7efe0000 0`00009000 ( 36.000 kb)
PEB 7ff`fffdf000 0`00001000 ( 4.000 kb)
These figures are slightly confusing, because it seems like only memory which is both MEM_PRIVATE and MEM_COMMIT has really been allocated by my program... The rest is in shared DLLs, and other areas. The lead me to try and count up all the MEM_PRIVATE,MEM_COMMIT segments by doing:
!address -f:VAR,MEM_PRIVATE,MEM_COMMIT
This gives output for each segment rather than each malloc... Here's a sample:
0`12bf0000 0`12bf1000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unclassified>
0`12cf0000 0`12cf5000 0`00005000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unclassified>
0`12e70000 0`12e75000 0`00005000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unclassified>
0`37f20000 0`37f21000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_EXECUTE_READWRITE <unclassified>
0`7ffe0000 0`7ffe1000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_READONLY <unclassified>
The 3rd column is segment size and if I add all these up for my program I get a total of 68Mb (Roughly double the sum total of all the allocations). So how do I rationalise these two figures? What governs the size of these segments and why does the total differ so much from all my allocations? Also, the size of all my allocations apears rather small compared to what appears in win7 task manager (Private working set).... So am I missing some memory use somewhere?