Linux gdb中的内存分配

Linux gdb中的内存分配,linux,memory-management,gdb,Linux,Memory Management,Gdb,为什么当我在gdb调试器中单步执行一个程序时,内存消耗会不可预测地跳跃?我试图用gdb来找出为什么一个程序使用的内存比它应该使用的要多,而且它不合作 我在监视进程内存使用情况的同时逐步查看了源代码,但由于两个原因,我找不到分配内存的行: 报告的内存使用量仅以64MB的增量增加(通常,但不一定总是如此)。我怀疑我看到了一些内存管理器的影响,我不知道哪些内存管理器一次保留64MB,并屏蔽了多个较小的分配 跳转不会发生在代码中的一致位置。它不仅在不同的gdb运行期间发生在不同的线路上;它有时也发生在不

为什么当我在
gdb
调试器中单步执行一个程序时,内存消耗会不可预测地跳跃?我试图用gdb来找出为什么一个程序使用的内存比它应该使用的要多,而且它不合作

我在监视进程内存使用情况的同时逐步查看了源代码,但由于两个原因,我找不到分配内存的行:

  • 报告的内存使用量仅以64MB的增量增加(通常,但不一定总是如此)。我怀疑我看到了一些内存管理器的影响,我不知道哪些内存管理器一次保留64MB,并屏蔽了多个较小的分配
  • 跳转不会发生在代码中的一致位置。它不仅在不同的gdb运行期间发生在不同的线路上;它有时也发生在不合逻辑的地方,比如(c++)函数的右括号。gdb本身是否可能影响内存分配
  • 有没有关于更有效的工具的想法/建议来帮助我深入到真正负责这些内存分配的代码行


    以下是一些相关的系统信息:我正在Windows下的虚拟CentOS linux机器上运行x86_64-redhat-linux-gnu版本7.2-64.el6-5.2。该程序是通过复杂的构建脚本在远程服务器上构建的,因此准确地跟踪在任何时候使用了哪些选项本身就有点麻烦。我通过
    top
    实用程序(“virt”或虚拟内存列)和读取实时监控文件
    /proc//status
    来监控内存使用情况,他们都同意。由于该程序使用了一大套第三方库,因此可能有一个或多个覆盖的
    malloc()
    函数涉及到我不知道的地方--查找它们是这项任务的一部分。

    gdb,由它自己的设备来处理,不会影响程序的内存使用,尽管由于其他原因,在gdb下运行可能与独立运行不同


    然而,这也取决于您使用gdb的方式。如果您只是设置简单的断点、单步执行和打印内容,那么就可以了。但有时,为了计算表达式,gdb会在底层分配内存。例如,如果您有一个断点条件,比如
    strcmp(arg,“string”)==0
    ,那么gdb将为该字符串常量分配内存。还有其他类似的情况。

    这个答案分为几个部分,因为发生了几件事:

  • Valgrind和Massif模块(一个内存分析器)在这个问题上比gdb更有用。有时使用调试器快速查看是可行的,有时则不然
  • top
    是一个分析内存使用情况的糟糕工具,因为它只报告虚拟内存分配,在本例中,虚拟内存分配大约是实际堆内存使用情况的3倍。当进程请求内存块时,Unix内核映射并提供虚拟内存,但不一定使用它。底层系统调用是
    mmap()
    。我仍然不知道如何检查块大小
    top
    只能告诉您Unix内核对内存消耗的了解,这还不够有用。不要使用它(或/proc/下的内存文件)进行详细的内存分析
  • 退出函数时的内存分配是由Autolock引起的——这是一个线程锁类,其析构函数在其超出范围时释放锁。然后,另一个线程开始运行并分配一些内存,使操作员(我)感到困惑。不可重复性可能是因为某些线程正在等待外部资源,如Internet连接

  • 你用过valgrind吗?这是我的第一个调用端口,在这类调查的
    gdb
    之前。valgrind定期检查我们的代码,尽管我对它不是很熟悉。我以为这只是为了寻找内存泄漏(?)我在这里寻找的似乎是膨胀的,但不是泄漏的。
    valgrind
    是容器工具;您可以使用
    memcheck
    组件检查泄漏,但它的工具集做的更多。这几乎是一个插件架构。我不确定是否有一个子工具可以满足您的需要,但它确实值得检查。请参阅博文。您可能希望使用该工具运行
    valgrind
    。最后一个问题的答案是:它可以选择运行。此外,客户端程序可以直接使用这些低级系统调用来分配内存。默认情况下,Massif不会测量这些。它也不测量代码、数据和BSS段的大小。因此,Massif报告的数字可能比top等工具报告的数字要小得多,这些工具用于测量程序在内存中的总大小。