我正在尝试了解我维护的程序的内存使用情况。我已经意识到,从进程转储中,我可以使用 windbg 执行“heap -a 0”来打印我的进程尚未删除的每个分配。每个分配看起来有点像:
0000000006a905c0: 000a0 。 000a0 [07] - 忙 (68),尾部填充 - 无法在 0000000006a90650 额外读取堆条目
68 是我分配的内存,000a0 是实际使用的内存量(因为有一点开销)。
如果我为我的程序添加所有这些分配,我得到 34Mb,但是,这似乎与 !address -summary 中的内存摘要关系不大,它显示:
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)
这些数字有点令人困惑,因为似乎只有 MEM_PRIVATE 和 MEM_COMMIT 内存真正被我的程序分配了……其余的在共享 DLL 和其他区域中。引导我尝试通过执行以下操作来计算所有 MEM_PRIVATE、MEM_COMMIT 段:
!address -f:VAR,MEM_PRIVATE,MEM_COMMIT
这给出了每个段的输出而不是每个 malloc...这是一个示例:
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>
第 3 列是段大小,如果我为我的程序将所有这些加起来,我得到总共 68Mb(大约是所有分配总和的两倍)。那么我如何合理化这两个数字呢?什么决定了这些部分的大小,为什么总数与我的所有分配有如此大的差异?此外,与 win7 任务管理器(专用工作集)中显示的相比,我所有分配的大小看起来相当小......所以我是否在某处遗漏了一些内存使用?
最佳答案
将您的分配加起来不会得到堆使用的总内存“私有(private)内存”。
首先,虚拟内存分配以 64KB 粒度完成,堆可能使用更大的 block 。私有(private)内存还包括所有不与其他进程共享(可共享)的内存。这包括使用 VirtualAlloc 分配的内存以及写时复制页面。
关于c++ - 为什么您的进程的私有(private)大小可以比您所做的分配数量大得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4911089/