是否有malloc实现在其自己的堆之外进行簿记?

时间:2010-12-17 00:54:59

标签: c opengl embedded malloc

我需要管理一个内存堆,其约束条件是该内存只能写入,永远不会读取,即malloc实现应该将簿记信息与它管理的堆分开,在普通堆上,并且应该在事实上永远不会触及它管理的特定堆。我希望使用经过测试,优化的现成解决方案,如果有的话。使用示例包括OpenGL VBO和嵌入式系统外部单元上的内存。

我瞥了一眼dlmalloc,从文档中,它似乎标记了从双方分配记账信息的内存块。谷歌搜索也没有任何好处 - 也许我没有合适的关键字来找到我正在寻找的东西。

澄清:作为一个单独的堆,我的意思是我定义为一个堆。我想在一个或少量预分配的块中紧密使用具有小分配的内存。我甚至不关心簿记信息(在这样管理的堆之外)是否大于里面的数据:)此外,应用程序本身将使用stock malloc和heap进行操作,并且只将这些块用于特殊目的,归结为内存区域,用于与外部硬件通信,其中来自应用程序的写入是目的,读取是不可能的或昂贵的。这不是一般的malloc问题,我只是希望利用许多研究和测试已经进入的东西。

6 个答案:

答案 0 :(得分:2)

  

实际上应该永远不会触及它管理的特定堆。

如果不管理堆怎么办?使用既不管理[heap]区域(参见/proc/$$/maps),也不将其元数据存储在可配置内存中的特定实现,请参阅此malloc函数,然后为您的程序提供唯一的可共存内存。

void *mymalloc(size_t len)
{
        void *x = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        return (x == (void *)-1) ? NULL : x;
}

现在,对于杀手的启示:glibc恰好使用了足够大的分配。

答案 1 :(得分:2)

它不是一个随时可用的库,但Linux内核中的resource management代码正是为了管理PCI地址空间等资源。

答案 2 :(得分:0)

这是一个非常简单的malloc实现,它永远不会将簿记信息写入它管理的堆中:

void *malloc(size_t n) { return sbrk(n); }
void free(void *p) { }
void *realloc(void *p, size_t n }
{
    void *q = malloc(n);
    if (q) memcpy(q, p, n);
    return q;
}

如果你想要一些更现实的想法,一个简单的解决方案是选择一个最小的内存单元进行分配(8或16个字节可能是合理的)并将托管堆分成这个大小的单元,然后存储哪些在位图中是空闲的(例如,每16字节一位,对于1/128,<1%的开销)。然后搜索可用空间O(n),但您可以考虑使用多尺度地图来改进它。

另一个想法是使用与dlmalloc相同的原则,但不是将数据存储在空闲块中,而是在块的地址上执行哈希以从哈希箱中获取其簿记信息。然而,任何类似的方法都没有在实际堆中存储信息的一个大问题是,释放内存可能会矛盾地增加正在使用的内存量(由于需要分配新的簿记)结构)。

答案 3 :(得分:0)

实现可能相当简单。不使用分配的块存储元数据的一个缺点是free()的性能可能更慢且不确定。但由于malloc()已经存在这个问题,或许这不是一个真正的问题。

一个简单的确定性解决方案是实现固定块内存分配器,其中固定大小的块从传统堆分配,并且指向每个块的指针放在队列或链表上。要分配一个块,您只需从空闲块队列/列表中获取一个指针,然后释放它,将指针放回到空闲块列表中。

答案 4 :(得分:0)

管理器是否需要与malloc / free具有相同的语义?如果你可以让你的分配函数返回一个指向结构的指针,而这个指针又会指向实际的内存,那么事情会大大简化。 deallocate函数将接受指向结构的指针,而不是指向内存的指针。

除此之外,分配方法将受到您的使用模式的极大影响。关于分配的大小,以及分配和释放内存块的模式,可以说什么?

答案 5 :(得分:0)

只需使用Buddy System