我正在用C++编写一个应用程序,它使用了一些外部开源库。我试图查看Ubuntu系统监视器,以获得有关我的进程如何使用资源的信息,我注意到常驻内存继续增加到非常大的值(超过100MiB)。这个应用程序应该在嵌入式设备上运行,所以我必须小心。
我开始认为应该有一个(一些)内存泄漏,所以我使用valgrind。不幸的是,valgrind似乎没有报告严重的内存泄漏,只是我正在使用的库中的一些小问题,仅此而已。
那么,我必须得出结论,我的算法真的使用了那么多内存吗?这对我来说似乎很奇怪。或者可能我误解了系统监视器列的含义?当与软件评测相关时,有人能在系统监视器中澄清“虚拟内存”、“驻留内存”、“可写内存”和“内存”的含义吗?我应该期望这些值立即表示我的进程在RAM中占用了多少内存吗?
在过去,我使用的工具能够告诉我我在哪里使用了内存,比如Apple Profiling。有没有类似的东西我也可以在Linux中使用?
谢谢!
发布于 2011-07-03 19:11:39
您可以尝试的另一个工具是/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)库函数将从操作系统请求100MB的存储空间(或者从空闲列表中处理它)。这100兆字节将被分配给mmap(..., MAP_ANONYMOUS),它实际上不会分配任何内存。(有关详细信息,请参阅malloc(3)页面末尾的声明。)操作系统将在第一次写入每个页面时提供内存。
虚拟内存代表映射到您的进程中的所有库和可执行对象以及您的堆栈空间。
驻留内存是RAM中实际存在的内存量。您可以链接到整个1.5兆字节的C库,但只使用支持标准IO接口所需的100k (胡乱猜测)的库。库的其余部分将在需要时从磁盘demand paged in。或者,如果您的系统处于内存压力之下,并且一些最近较少使用的数据被调出到交换空间,那么它将不再计入驻留内存。
可写内存是您的进程分配的具有写权限的地址空间量。(例如,检查shell的pmap(1)命令:pmap $$的输出,查看哪些页面映射到了哪些文件、匿名空间、堆栈以及这些页面上的权限。)这是程序在最坏的交换场景中可能需要多少交换空间的合理指示,当所有内容都必须分页到磁盘时,或者进程为自己使用了多少内存。
因为在同一时间您的系统上可能有50--100个进程,并且几乎所有的进程都链接到标准C库上,所以所有的进程都可以共享库的只读内存映射。(它们还可以共享使用mmap(..., MAP_PRIVATE|PROT_WRITE)打开的任何文件的所有写入时复制私有可写映射,直到进程写入内存为止。)top(1)工具将在SHR列中报告可以在进程之间共享的内存量。(请注意,内存可能不是共享的,但其中一些内存(libc)肯定是共享的。)
记忆是非常模糊的。我不知道这是什么意思。
https://stackoverflow.com/questions/6562431
复制相似问题