C语言内存分析工具

9

我需要一个内存分析器来了解每个函数的内存使用情况。我知道 valgrind(Massif),但它不能提供有关特定函数的信息(至少,我不知道如何在 Massif 中做到这一点)。

您知道在 Linux 上有什么工具可以实现此目的吗?

谢谢!


这是关于堆内存的。代码使用了大量的数据,我需要知道哪个函数在分配它。虽然释放可能发生在其他函数中,但如果函数A分配了16Gb而机器只有8Gb,则计算机开始交换(即使后面的函数B将对其进行释放也无济于事)。 - lezo
为什么需要一次性分配16G内存?我认为你应该重新考虑你的需求和设计。 - Vikram.exe
1
@Vikram.exe - 你说得对,但为了回答那个问题,他需要来自分析器的结果 :-) (记住 - 他可能正在维护由其他人编写的代码,即使不是,系统的实际行为通常也是不可预测的 :-)) - psmears
4个回答

7

6
如果您只想获取请求大量内存的位置,最简单的方法是修补malloc函数或创建一个新的库,其中包含malloc调用,并从您的malloc函数跟踪大小。我不是在谈论实现malloc调用。将此库LD_PRELOAD到您的应用程序中。
以下是示例代码:
/*
 * gcc -shared -fPIC foo.c -ldl -Wl,-init,init_lib -o libfoo.so
 *
 * LD_PRELOAD this library in the environment of the target executable
 *
 */

#include <stdio.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <sys/errno.h>

#ifndef RTLD_NEXT
#define RTLD_NEXT ((void *)-1)
#endif

int init_lib(void)
{
    return 0;
}

void *malloc(size_t size)
{
    /* do required checks on size here */

    return ((void* (*)(size_t))(dlsym(RTLD_NEXT, "malloc")))(size);
}

你完全可以修改这段代码来完成一些额外的操作。


1
谁给它点了踩,能否请您说明原因? - Vikram.exe
1
我点赞是因为这远非错误。 - jweyrich
1
谢谢Jweyrich,但我仍然想知道为什么它被投票否决了。 - Vikram.exe
1
@Vikram.exe 如果在malloc函数内部使用printf(或类似的调用malloc的函数),则此方法将无法正常工作,因为它会创建无限递归。 - Darshan Prajapati

4
Massif可以显示出程序中内存使用量较高的函数,但前提是程序需要编译时加上调试信息(-g),它甚至可以显示出函数所在的行号。
ms_print输出的图像下方的每个详细快照中,这些信息会以调用树的形式呈现。可以通过--detailed-freq选项控制生成详细快照的频率。有关读取详细快照信息的详细信息,请参见Massif手册的9.2.6节

信息并不太友好(像valgrind中通常的那样),但它确实提供了有关函数的信息。有一个工具(massif visualizer http://kde-apps.org/content/show.php/Massif+Visualizer?content=122409)似乎可以通过彩色图形解决这个问题。我还没有尝试过,但在截图中看起来很棒! - lezo

2
正如其他人指出的那样,Massif提供了详尽的性能分析信息,但会显著减慢进程速度。
另一个选择是Google的tcmalloc,它具有嵌入式堆剖析器,可以转储带有分配的调用图(请参见http://goog-perftools.sourceforge.net/doc/heap_profiler.html),也可以以图形方式显示。
您可以使用LD_PRELOAD将其与程序动态链接,并使用HEAPPROFILE环境变量启用堆剖析器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接