c++ - 为什么您的进程的私有(private)大小可以比您所做的分配数量大得多?

标签 c++ c windows memory-management windbg

我正在尝试了解我维护的程序的内存使用情况。我已经意识到,从进程转储中,我可以使用 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/

相关文章:

c++ - 找到 2 个等和子序列,具有最大和?

C - regexec 返回 NOMATCH - 即使它应该?

c - makefile 中是否忽略了扩展名?

windows - 如何在 Windows 下使用特定的 PATH 安装 tomcat?

windows - 为什么 msi 安装程序是使用 Windows 安装程序 xml 创建的,即仅 wix?

c++ - 如何在单元测试框架 Google Test 中组合测试过滤器?

c++ - 素数计划

C++ Catch Framework 处理C的assert?

c - 如何在 Win 64 位上构建 gsl-1.8(GNU 统计库)

c++ - 如何使用 Qt 应用程序发送传真?