【问题标题】:Total glibc malloc() bytes总 glibc malloc() 字节
【发布时间】:2014-07-28 13:32:37
【问题描述】:

如何获取程序中 malloc() 的总字节数(假设我使用 glibc 运行)? 我不想看到程序占用了多少内存,我想看看我分配了多少内存。下面是一个示例程序,其中这些数字会非常不同。

#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main() {
    vector<void *> p;
    printf("Allocating...\n");
    for (size_t i = 0; i < 1024 * 1024 * 10; ++i) {
        p.push_back(malloc(1024));
        memset(*p.rbegin(), 0, 1024);
    }
    printf("Press return to continue...\n");
    getchar();
    printf("Freeing all but last...\n");
    for (size_t i = 0; i < p.size() - 1; ++i)
        free(p[i]);
    printf("Press return to continue...\n");
    getchar();

    // UNTIL THIS FREE, TOP WOULD SHOW THIS PROGRAM TAKES 16G,
    // BUT THE TOTAL MALLOC() SIZE IS MUCH LESS.

    printf("Freeing last...\n");
    free(*p.rbegin()); 
    printf("Press return to continue...\n");
    getchar();
}

我知道这可以通过 LD_PRELOAD 或通过我自己的 malloc 和 free 函数来实现,但是有没有更简单的方法来获得 malloc() 的总数?

【问题讨论】:

  • 您必须自己计算。也许使用一个宏来调用您自己的扩展 malloc 函数:#define MALLOC my_malloc。
  • 不错,呃,“C++”在这里。
  • tcmalloc,来自 Google,拥有大量可访问的统计信息,因此一旦您拥有 LD_PRELOADed 它,您就可以使用它的特定功能来查询它的状态。
  • (即使你对 libc 感兴趣,你的代码也是 C++(尤其是使用vector 模板))

标签: c++ memory memory-management malloc heap-memory


【解决方案1】:

各种语言标准说:

没有独立于平台的方式来获取此信息。 malloc 的不同实现可能会提供此信息,但它会以非标准方式提供。

Glibc 提供:

  • 您可以使用__malloc_hook 功能编写一个挂钩来计算已分配的内存量。

  • 还有mallinfo(),它应该提供一些关于已分配内存的信息。

【讨论】:

  • 已编辑以标记我对 libc 感兴趣。还在等着看是否有比使用钩子更简单的工具。如果不是,将您标记为正确。
【解决方案2】:

创建一个全局变量和你自己的malloc()函数

static size_t count;

void *malloc_ex(size_t n)
{
    count+=n;
    return malloc(n);
}

那么您现在可以随时通过查看countvariable 来分配多少字节。

编译器将全局变量初始化为0,这样就可以了。 请不要 #undef malloc 和将 #define 回复为 malloc_ex() 这将是未定义的行为。

【讨论】:

  • 还应定义一个额外的 free_ex() 函数以减少分配的内存量,这还需要控制每次调用 malloc_ex 时分配的内存量。
  • 我推荐#define MALLOC malloc_ex和#define FREE free_ex。
  • @FiddlingBits:我认为你需要写一个为什么你推荐这些宏的动机。
  • @ThomasPadron-McCarthy 所以调用是一致的并且易于扩展。对不起教授。 :-D
  • @Claudix,您将如何跟踪分配的内存量?您说,“还需要控制每次调用 malloc_ex 时分配的内存量。”,但没有指明机制。顺便说一句,我认为你的答案比这个更好。你只需要填充你的结构。
【解决方案3】:

您应该定义两个函数并分配额外的空间来跟踪每次调用自定义分配器函数所分配的内存。

//Space to store the size of an allocation
struct _room {
    size_t sz;  //Chunk size     
    char padding[16-(sizeof(size_t) % 16)]; //Force 16-byte alignment   
}

//A global variable to keep track of the total amount of memory allocated (except the extra space of storing chunk sizes
static size_t TOTAL = 0;


//Custom allocator
void *mymalloc(size_t sz) {
    //Allocate memory plus room for storing the chunk size. We'll need it later in 
    //myfree() to appropriately decrement TOTAL.
    struct _room *r = (struct _room *) malloc(sz + sizeof(struct _room));
    r->sz = sz;
    TOTAL += sz; //keep track of user allocated memory
    return (void *) (r+1); //Pointer to usable memory
}

void myfree(void *m) {
    //Point to the register with chunk size, given the memory pointer returned my mymalloc()
    struct _room *r = ((struct _room *) m) - 1;
    TOTAL -= r->sz; //Update total
    free((void*)r); //Free all memory: room + user memory
}

【讨论】:

  • 如果你这样做,你冒着破坏 malloc 原生对齐的风险,例如在某些平台上,malloc 是 16 字节对齐的,该平台的代码可能依赖于这种对齐方式。
  • 我知道有编译器指令可以强制结构对齐。如何修复我的代码以实现 16 字节对齐?
  • 有多种方法来处理这个问题,但一种方法是填充 struct _room 以保持平台的最小对齐,例如对于 Mac OS X,malloc 始终至少 16 字节对齐,您可以填充 struct _room 使其大小为 16 字节。
  • 好的,我已经添加了 pad 来填充所需的 16 字节空间。
  • @Claudix 你需要在mymalloc()中设置r-&gt;sz。
猜你喜欢
  • 2014-05-31
  • 2018-04-04
  • 2016-12-03
  • 2020-09-17
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
相关资源
最近更新 更多