Ubuntu System Monitor和valgrind发现C ++应用程序中的内存泄漏 [英] Ubuntu System Monitor and valgrind to discover memory leaks in C++ applications

查看:150
本文介绍了Ubuntu System Monitor和valgrind发现C ++应用程序中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

谢谢!

解决方案

另一个可以尝试的工具是/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 MB的存储(或从空闲列表中进行处理). 100兆字节将分配有mmap(..., MAP_ANONYMOUS)实际上不会分配任何内存. (有关详细信息,请参见malloc(3)页末尾的rant.)操作系统将在首次写入每页时提供内存.

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

常驻内存是RAM中实际 的内存量.您可以链接整个1.5兆字节的C库,但只能使用支持标准IO接口所需的库的100k(随意猜测).需要时,库的其余部分将从磁盘中按需分页.或者,如果您的系统承受内存压力,并且一些最近使用的数据被调出以便交换,它将不再计入常驻内存.

可写内存是您的进程使用写特权分配的地址空间量. (例如,检查外壳程序的pmap(1)命令:pmap $$的输出,以查看哪些页面映射到了哪些文件,匿名空间,堆栈以及这些页面上的特权.)这是对的合理说明.在最坏情况下的交换情况下,程序什么可能需要多少交换空间,什么时候所有内容都必须分页到磁盘上,或者进程自己使用了多少内存? /p>

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

内存非常模糊.我不知道这是什么意思.

I'm writing an application in C++ which uses some external open source libraries. I tried to look at the Ubuntu System Monitor to have information about how my process uses resources, and I noticed that resident memory continues to increase to very large values (over 100MiB). This application should run in an embedded device, so I have to be careful.

I started to think there should be a (some) memory leak(s), so I'm using valgrind. Unfortunately it seems valgrind is not reporting significant memory leaks, only some minor issues in the libraries I'm using, nothing more.

So, do I have to conclude that my algorithm really uses that much memory? It seems very strange to me... Or maybe I'm misunderstanding the meaning of the columns of the System Monitor? Can someone clarify the meaning of "Virtual Memory", "Resident Memory", "Writable Memory" and "Memory" in the System Monitor when related to software profiling? Should I expect those values to immediately represent how much memory my process is taking in RAM?

In the past I've used tools that were able to tell me where I was using memory, like Apple Profiling Tools. Is there anything similar I can use in Linux as well?

Thanks!

解决方案

Another tool you can try is the /lib/libmemusage.so library:

$ 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% =
...

(I quit vim immediately after startup.)

Maybe the histogram of block sizes will give you enough information to tell where leaks may be happening.

valgrind is very configurable; --leak-check=full --show-reachable=yes might be a good starting point, if you haven't tried it yet.


"Virtual Memory", "Resident Memory", "Writable Memory" and "Memory"

Virtual memory is the address space that your application has allocated. If you run malloc(1024*1024*100);, the malloc(3) library function will request 100 megabytes of storage from the operating system (or handle it out of the free lists). The 100 megabytes will be allocated with mmap(..., MAP_ANONYMOUS), which won't actually allocate any memory. (See the rant at the end of the malloc(3) page for details.) The OS will provide memory the first time each page is written.

Virtual memory accounts for all the libraries and executable objects that are mapped into your process, as well as your stack space.

Resident memory is the amount of memory that is actually in RAM. You might link against the entire 1.5 megabyte C library, but only use the 100k (wild guess) of the library required to support the Standard IO interface. The rest of the library will be demand paged in from disk when it is needed. Or, if your system is under memory pressure and some less-recently-used data is paged out to swap, it will no longer count against Resident memory.

Writable memory is the amount of address space that your process has allocated with write privileges. (Check the output of pmap(1) command: pmap $$ for the shell, for example, to see which pages are mapped to which files, anonymous space, the stack, and the privileges on those pages.) This is a reasonable indication of how much swap space the program might require in a worst-case swapping scenario, when everything must be paged to disk, or how much memory the process is using for itself.

Because there are probably 50--100 processes on your system at a time, and almost all of them are linked against the standard C library, all the processes get to share the read-only memory mappings for the library. (They also get to share all the copy-on-write private writable mappings for any files opened with mmap(..., MAP_PRIVATE|PROT_WRITE), until the process writes to the memory.) The top(1) tool will report the amount of memory that can be shared among processes in the SHR column. (Note that the memory might not be shared, but some of it (libc) definitely is shared.)

Memory is very vague. I don't know what it means.

这篇关于Ubuntu System Monitor和valgrind发现C ++应用程序中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆