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

Luc*_*lon 6 c++ linux valgrind memory-leaks

我正在用C++编写一个使用一些外部开源库的应用程序.我试着查看Ubuntu系统监视器以获取有关我的进程如何使用资源的信息,并且我注意到常驻内存继续增加到非常大的值(超过100MiB).这个应用程序应该在嵌入式设备中运行,所以我必须要小心.

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

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

在过去,我使用的工具能够告诉我在哪里使用内存,比如Apple Profiling Tools.我可以在Linux中使用类似的东西吗?

谢谢!

sar*_*old 6

您可以尝试的另一个工具是/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% =
...
Run Code Online (Sandbox Code Playgroud)

(我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(疯狂猜测).当需要时,将从磁盘中请求库的其余部分.或者,如果您的系统处于内存压力之下,并且一些较少使用的数据被分页以进行交换,则它将不再计入驻留内存.

可写内存是进程使用写权限分配的地址空间量.(检查pmap(1)命令的输出:pmap $$例如,对于shell,查看哪些页面映射到哪些文件,匿名空间,堆栈以及这些页面上的权限.)这是程序交换空间多少的合理指示.可能需要在最坏情况下交换场景,当所有内容都必须被分页到磁盘,或者进程为自己使用多少内存时.

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

记忆非常模糊.我不知道这意味着什么.