跟踪每个函数的内存分配

Posted

技术标签:

【中文标题】跟踪每个函数的内存分配【英文标题】:Track memory allocation per function 【发布时间】:2014-03-08 03:15:40 【问题描述】:

所以我知道我可以使用全局重载 new 的方法来跟踪内存分配,如下所示:http://www.almostinfinite.com/memtrack.html

但是,我想知道是否有一个好方法可以为每个函数执行此操作,以便我可以获得每个函数分配多少的报告。现在我可以在我提供的链接中获取文件和行以及 typeid 是什么,但我想找到分配最多的函数。

【问题讨论】:

可能是一个很好的内存分析工具提供这个(不确定,如果 valgrind 允许这样做)。 我真的不想要像 valgrind 这样重的东西,因为在运行期间时间信息是无用的 是的,找一些基于代码注入的分析工具可能会更好。 @mockinterface 您显然没有阅读我链接的内容或我理解我可以重载 new 但我想要每个函数粒度的问题,并且似乎没有这样做的好方法跨度> 为什么不使用 valgrind? 【参考方案1】:

怎么样做类似的事情:http://ideone.com/Wqjkrw

#include <iostream>
#include <cstring>

class MemTracker

    private:
        static char func_name[100];
        static size_t current_size;

    public:
        MemTracker(const char* FuncName) strcpy(&func_name[0], FuncName);
        static void inc(size_t amount) current_size += amount;
        static void print() std::cout<<func_name<<" allocated: "<<current_size<<" bytes.\n";
        static void reset() current_size = 0; memset(&func_name[0], 0, sizeof(func_name)/sizeof(char));
;

char MemTracker::func_name[100] = 0;
size_t MemTracker::current_size = 0;


void* operator new(size_t size)

    MemTracker::inc(size);
    return malloc(size);


void operator delete(void* ptr)

    free(ptr);



void FuncOne()

    MemTracker(__func__);

    int* i = new int[100];
    delete[] i;
    i = new int[200];
    delete[] i;

    MemTracker::print();
    MemTracker::reset();


void FuncTwo()

    MemTracker(__func__);
    char* c = new char[1024];
    delete[] c;
    c = new char[2048];
    delete[] c;

    MemTracker::print();
    MemTracker::reset();


int main()

    FuncOne();
    FuncTwo();
    FuncTwo();
    FuncTwo();
    return 0;

打印:

FuncOne allocated: 1200 bytes.
FuncTwo allocated: 3072 bytes.
FuncTwo allocated: 3072 bytes.
FuncTwo allocated: 3072 bytes.

【讨论】:

嗯,这很有趣,但是如果您多次运行 FuncTwo(),您会看到它不会像在这种情况下那样以恒定值增长,因为没有任何变化所以它不会t 似乎准确。 __func__ 也是标准的吗? 另外,这需要用户手动添加 global_alloc make pair 我希望是自动的东西 ideone.com/Wqjkrw 会做..我试图通过使其重置并在析构函数中打印来使其自动化,但由于某种原因它搞砸了..这可能是我能想到的最好的。 . 除此之外,您可能必须实际下载内存分析器。 没有任何真正的方法可以自动将其包含在所有功能中,但有吗?我说的原因是,如果我在全局范围内替换 new,我可以选择在任何时候通过删除新函数的重载来删除它,或者如果我想要的话将它添加回来。有了这个,总是包含该对象占用内存。【参考方案2】:

您使用的是什么平台?可能存在特定于平台的解决方案,而无需更改代码库中的功能。

如果您使用的是 Microsoft Visual Studio,您可以使用编译器开关 /Gh 和 /GH 让编译器调用您可以定义的函数 _penter_pexit。在这些函数中,您可以查询程序正在使用多少内存。里面应该有足够的信息来计算每个函数分配了多少内存。

MSDN article 中提供了检查内存使用情况的示例代码。

【讨论】:

我需要跨平台的东西

以上是关于跟踪每个函数的内存分配的主要内容,如果未能解决你的问题,请参考以下文章

通过分配大量内存来跟踪堆损坏?

gdb可以跟踪内存分配日志

如何在 C++ 中跟踪内存分配(尤其是新建/删除)

在 cpp 中重新定义 new 和 delete 运算符以跟踪内存分配:无法跟踪整个内存块的删除大小

带指针的内存管理

JVM中的本机内存跟踪