Ubuntu System Monitor和valgrind在C ++应用程序中发现内存泄漏

我用C ++编写了一个应用程序,它使用了一些外部的开源库。 我试图看看Ubuntu系统监视器有关于我的过程如何使用资源的信息,我注意到驻留内存继续增加到非常大的值(超过100MiB)。 这个应用程序应该在embedded式设备上运行,所以我必须小心。

我开始认为应该有(一些)内存泄漏,所以我使用valgrind。 不幸的是,似乎valgrind没有报告显着的内存泄漏,只有我使用的库中的一些小问题,仅此而已。

那么,我是否必须得出结论:我的algorithm真的使用了那么多的内存? 对我来说这似乎很奇怪…或者,我误解了系统监视器列的含义? 在与软件分析相关的时候,有人能澄清系统监视器中“虚拟内存”,“驻留内存”,“可写内存”和“内存”的含义吗? 我应该期望这些值能够立即表示我的进程在RAM中占用了多less内存?

在过去,我使用了能够告诉我在哪里使用内存的工具,比如Apple Profiling Tools。 有什么类似的我可以在Linux中使用?

谢谢!

Solutions Collecting From Web of "Ubuntu System Monitor和valgrind在C ++应用程序中发现内存泄漏"

您可以尝试的另一个工具是/lib/libmemusage.so库:

 $ LD_PRELOAD=/lib/libmemusage.so vim Memory usage summary: heap total: 4643025, heap peak: 997580, stack peak: 26160 total calls total memory failed calls malloc| 42346 4528378 0 realloc| 52 7988 0 (nomove:26, dec:0, free:0) calloc| 34 106659 0 free| 28622 3720100 Histogram for block sizes: 0-15 14226 33% ================================================== 16-31 8618 20% ============================== 32-47 1433 3% ===== 48-63 4174 9% ============== 64-79 4736 11% ================ 80-95 313 <1% = ... 

(我在启动后立即退出vim 。)

也许块大小的直方图会给你足够的信息来告诉可能发生泄漏的地方。

valgrind是非常可配置的; --leak-check=full --show-reachable=yes可能是一个很好的起点,如果你还没有尝试过。


“虚拟内存”,“驻留内存”,“可写内存”和“内存”

虚拟内存是您的应用程序分配的地址空间。 如果你运行malloc(1024*1024*100);malloc(3)库函数将从操作系统请求100兆字节的存储空间(或将其从空闲列表中处理出来)。 100兆字节将被分配mmap(..., MAP_ANONYMOUS)实际上不会分配任何内存 。 (有关详细信息,请参阅malloc(3)页末尾的提示。)操作系统将在每个页面首次写入时提供内存。

虚拟内存负责映射到进程中的所有库和可执行对象以及堆栈空间。

驻留内存是实际在RAM中的内存量 。 您可能会链接整个1.5兆字节的C库,但只能使用支持标准IO接口所需库的100k(疯狂猜测)。 需要时, 磁带库的其余部分将从磁盘分页 。 或者,如果您的系统处于内存压力下,并且某些较少使用的数据将被换出,则不再计入驻留内存

可写内存是您的进程使用写权限分配的地址空间量。 (检查shell的pmap(1)命令: pmap $$的输出,例如查看哪些页面映射到哪些文件,匿名空间,堆栈以及这些页面上的权限。)这是一个合理的指示在最糟糕的交换场景中,程序可能需要多少交换空间,何时必须将所有内容分页到磁盘,或者进程本身使用多少内存。

由于系统中一次可能有50-100个进程,几乎所有进程都与标准C库链接,因此所有进程都可以共享该库的只读内存映射。 (他们还可以共享所有使用mmap(..., MAP_PRIVATE|PROT_WRITE)打开的文件的写入时拷贝专用可写映射,直到进程写入内存为止。) top(1)工具将报告可以SHR列中的进程之间共享的内存量。 (请注意,内存可能共享,但其中一些( libc )肯定是共享的。)

记忆非常模糊。 我不知道这是什么意思。