debugging 什么是私有字节、虚拟字节、工作集?

1aaf6o9v  于 2023-06-23  发布在  其他
关注(0)|答案(4)|浏览(125)

我正在尝试使用perfmon windows实用程序调试进程中的内存泄漏。
以下是perfmon解释术语的方式:

Working Set是此进程的工作集的当前大小,以字节为单位。工作集是进程中的线程最近访问的内存页的集合。如果计算机中的可用内存高于阈值,则即使页未在使用中,也会将其保留在进程的工作集中。当可用内存低于阈值时,将从工作集中修剪页。如果需要它们,则在离开主内存之前,它们将被软故障恢复到工作集。
Virtual Bytes是进程正在使用的虚拟地址空间的当前大小(以字节为单位)。虚拟地址空间的使用不一定意味着磁盘或主存储器页的对应使用。虚拟空间是有限的,并且进程可以限制其加载库的能力。
Private Bytes是此进程已分配的不能与其他进程共享的内存的当前大小(以字节为单位)。

这些是我的问题:

  • 我是否应该测量私有字节以确定进程是否有任何泄漏,因为它不涉及任何共享库,并且任何泄漏(如果发生)将来自进程本身?*
  • 进程消耗的总内存是多少?它是虚拟字节还是虚拟字节和工作集的总和?*
  • 私有字节、工作集和虚拟字节之间有什么关系吗?*
  • 是否有其他工具给予更好地了解内存使用情况?*
am46iovg

am46iovg1#

这个问题的简短答案是这些值都不是一个可执行文件实际使用的内存量的可靠指示器,也没有一个真正适合调试内存泄漏。

Private Bytes指的是进程可执行文件 * 请求 * 的内存量-不一定是它 * 实际使用 * 的量。它们是“私有的”,因为它们(通常)排除内存Map文件(即共享DLL)。但是--这里有一个问题--它们不一定排除那些文件分配的内存 *。无法判断私有字节的变化是由于可执行文件本身还是由于链接库。私有字节也是排他的物理内存;它们可以被分页到磁盘或在备用页列表中(即,不再使用,但也未被寻呼)。
工作集指进程使用的总物理内存。但是,与私有字节不同,它还包括内存Map文件和各种其他资源,因此它的测量精度甚至低于私有字节。这与任务管理器的“内存使用情况”中报告的值相同,近年来它一直是无数困惑的根源。工作集中的存储器是“物理的”,在这个意义上,它可以在没有页面错误的情况下寻址;然而,备用页列表 * 也 * 在物理上仍然在内存中,但在工作集中没有报告,这就是为什么当您最小化应用程序时,您可能会看到“内存使用率”突然下降的原因。
Virtual Bytes是整个进程占用的虚拟地址空间总和。这类似于工作集,因为它包括内存Map文件(共享DLL),但它也包括备用列表中的数据和已经分页出来并位于磁盘某处页面文件中的数据。在重负载下,系统上每个进程使用的虚拟字节总数将大大超过机器实际拥有的内存。

所以这些关系是:

  • 私有字节是您的应用实际分配的字节数,但包括页面文件使用量;
  • 工作集是非分页的私有字节加上内存Map文件;
  • 虚拟字节是工作集加上分页专用字节和备用列表。

这里还有一个问题正如共享库可以在应用程序模块内分配内存,导致应用程序的Private Bytes中报告潜在的误报一样,your 应用程序也可能最终在 shared 模块内分配内存,导致误报 negatives。这意味着您的应用程序实际上有可能存在一个内存泄漏,而这种泄漏根本不会在私有字节中显示出来。不太可能但有可能
私有字节是您的可执行文件正在使用的内存量的合理近似,可以用来帮助缩小内存泄漏的潜在候选列表;如果你看到这个数字不断地增长,无休止地增长,你会想检查这个过程是否有漏洞。然而,这不能 * 证明 * 存在或不存在泄漏。
在Windows中检测/纠正内存泄漏的最有效工具之一实际上是Visual Studio(链接转到使用VS处理内存泄漏的页面,而不是产品页面)。Rational Purify是另一种可能性。微软在这个问题上也有一个更通用的best practices document。这个previous question中列出了更多的工具。
我希望这能澄清一些事情!跟踪内存泄漏是调试中最困难的事情之一。祝你好运

xxe27gdn

xxe27gdn2#

perfmon计数器的定义从一开始就被打破了,出于某种原因似乎太难纠正。
MSDN上的视频“Mysteries of Memory Management Revealed“中提供了Windows内存管理的良好概述:它涵盖了比跟踪内存泄漏所需的更多的主题(例如工作集管理),但在相关主题中给出了足够的细节。
为了给予你一个关于perfmon计数器描述问题的提示,下面是MSDN上来自“Private Bytes Performance Counter -- Beware!”的私有字节的内幕:
问:什么时候私有字节不是私有字节?
A:当它不是常驻。
Private Bytes计数器报告进程的提交费用。也就是说,在交换文件中分配的空间量,用于在私有内存被交换出的情况下保存私有内存的内容。注意:我避免使用“reserved”这个词,因为可能会与处于未提交的保留状态的虚拟内存混淆。
从MSDN上的“Performance Planning“:
3.3专用字节
3.3.1说明
私有内存是指分配给一个进程的内存,不能被其他进程共享。当在一台机器上执行多个这样的进程时,该内存比共享内存更昂贵。(传统的)非托管dll中的私有内存通常由C++静态组成,大约占dll总工作集的5%。

bsxbgnwa

bsxbgnwa3#

您不应该尝试使用perfmon、任务管理器或任何类似的工具来确定内存泄漏。它们有助于识别趋势,但除此之外就没什么用了。他们报告的绝对值太模糊,而且聚合起来对特定任务(如内存泄漏检测)没有用处。
以前对这个问题的回答已经很好地解释了各种类型是什么。
您询问工具建议:我推荐Memory Validator。能够监控进行数十亿次内存分配的应用程序。
http://www.softwareverify.com/cpp/memory/index.html
免责声明:我设计了内存验证器。

z2acfund

z2acfund4#

这里有一个有趣的讨论: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);

则专用字节正确地反映分配和解除分配。

相关问题