什么是专用字节,虚拟字节,工作集?

我正在尝试使用perfmon windows实用程序来调试进程中的内存泄漏。

这就是perfmon解释术语的方式:

工作集是此进程的工作集的当前大小(以字节为单位)。 工作集是进程中线程最近触及的一组内存页面。 如果计算机中的可用内存超过阈值,即使它们未被使用,页面也会留在进程的工作集中。 当可用内存低于阈值时,页面将从工作集中删除。 如果需要他们,他们将在离开主存之前被软件故障重新放回工作集。

虚拟字节是进程正在使用的虚拟地址空间的当前大小(以字节为单位)。 使用虚拟地址空间不一定意味着相应使用磁盘或主内存页面。 虚拟空间是有限的,并且该过程可能会限制其加载库的能力。

专用字节是当前大小(以字节为单位)的此进程分配的内存,不能与其他进程共享。

这些是我有的问题:

是我应该测量的私人字节,以确定该进程是否有任何泄漏,因为它不涉及任何共享库,并且如果发生任何泄漏,将来自该进程本身?

该进程消耗的内存总量是多少? 它是虚拟字节还是虚拟字节和工作集的总和?

私人字节,工作集和虚拟字节之间是否有任何关系?

有没有其他工具可以更好地了解内存使用情况?


这个问题的简短答案是, 这些值都不是可执行程序实际使用内存量的可靠指标,它们都不适合调试内存泄漏。

专用字节是指进程可执行文件所要求的内存数量 - 不一定是实际使用的数量。 它们是“私有”的,因为它们(通常)不包括内存映射文件(即共享DLL)。 但是 - 这里有个问题 - 它们不一定排除那些文件分配的内存。 无法确定专用字节的更改是由于可执行文件本身还是由于链接的库引起的。 专用字节也不是唯一的物理内存; 他们可以分页到磁盘或待机页面列表(即不再使用,但也不分页)。

工作集是指进程使用的总物理内存(RAM)。 但是,与专用字节不同,这还包括内存映射文件和各种其他资源,所以它比专用字节更不准确。 这与在任务管理器的“内存使用情况”中报告的值相同,并且近年来一直是无穷无尽的混乱。 工作集中的内存是“物理”的,因为它可以在没有页面错误的情况下被处理; 但是,备用页面列表还在物理上位于内存中,但未在工作集中报告,这就是为什么当您最小化应用程序时,您可能会看到“内存使用量”突然下降的原因。

虚拟字节是整个进程占用的总虚拟地址空间 。 这就像工作集,它包含内存映射文件(共享DLL),但它也包括备用列表中的数据以及已经被分页并位于磁盘上某个页面文件中的数据。 在重负载下,系统上每个进程使用的虚拟字节总数将比机器实际存储的内存大得多。

所以这些关系是:

  • 私人字节是您的应用实际分配的内容,但包含页面文件的使用情况;
  • 工作集是非分页的专用字节加内存映射文件;
  • 虚拟字节是工作集加分页的专用字节和备用列表。
  • 这里还有一个问题。 就像共享库可以在您的应用程序模块内部分配内存一样,导致您的应用程序的专用字节中报告可能的误报,您的应用程序也可能最终在共享模块内部分配内存,从而导致误报。 这意味着实际上您的应用程序可能会出现内存泄漏,而这些内存泄漏永远不会显示在Private字节中。 不太可能,但可能。

    专用字节是您的可执行程序正在使用的内存量的合理近似值 ,可用于帮助缩小可能的内存泄漏候选列表的范围; 如果您看到这个数字在不断增长并且不断增长,那么您会想要检查该流程是否存在泄漏。 但是,这不能证明存在或不存在泄漏。

    在Windows中检测/纠正内存泄漏的最有效工具之一实际上是Visual Studio(链接转到使用VS进行内存泄漏的页面,而不是产品页面)。 理性净化是另一种可能性。 微软在这个问题上也有一个更一般的最佳实践文档。 上一个问题中列出了更多工具。

    我希望这会清除一些东西! 跟踪内存泄漏是调试中最难的事情之一。 祝你好运。


    您不应该尝试使用perfmon,任务管理器或类似的工具来确定内存泄漏。 它们对于识别趋势很有帮助,但不是其他的。 他们以绝对值形式报告的数字过于模糊,并且对于特定任务(如内存泄漏检测)非常有用。

    以前对这个问题的回答给出了各种类型的很好的解释。

    你问一个工具推荐:我推荐Memory Validator。 能够监视数十亿内存分配的应用程序。

    http://www.softwareverify.com/cpp/memory/index.html

    免责声明:我设计了Memory Validator。


    这里有一个有趣的讨论:http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/我对这个线程的理解是释放小分配是没有反映在私人字节或工作集。

    长话短说:

    如果我打电话

    p=malloc(1000);
    free(p);
    

    那么专用字节仅反映分配,而不是释放。

    如果我打电话

    p=malloc(>512k);
    free(p);
    

    那么专用字节正确地反映了分配和解除分配。

    链接地址: http://www.djcxy.com/p/14067.html

    上一篇: What is private bytes, virtual bytes, working set?

    下一篇: How to measure actual memory usage of an application or process?