通过切割一个大的malloc内存来减少malloc调用

时间:2012-09-25 13:56:09

标签: c memory malloc dynamic-allocation

首先,here是我从中获得想法的地方:

  

曾经有一个我写的应用程序使用了大量的小blob   内存,每个都分配有malloc()。它工作正常,但是   慢。我用一个替换了对malloc的多次调用,然后   在我的应用程序中切掉那个大块。它快得多。

我正在分析我的应用程序,当我减少malloc调用次数时,我得到了意想不到的良好性能提升。不过,我仍在分配相同数量的内存。

所以,我想做这个人做的事情,但我不确定最好的方法是什么。

我的想法:

// static global variables
static void * memoryForStruct1 = malloc(sizeof(Struct1) * 10000);
int struct1Index = 0;
...
// somewhere, I need memory, fast:
Struct1* data = memoryForStruct1[struct1Index++];
...
// done with data:
--struct1Index;

陷阱:

  • 我必须确保我不超过10000
  • 我必须按照我占用的顺序释放内存。 (在我的情况下不是主要问题,因为我正在使用递归,但如果可能的话我想避免使用它。)

受到Mihai Maruseac的启发:

首先,我创建了int的链接列表,它基本上告诉我哪些内存索引是免费的。然后我在我的结构中添加了一个名为int memoryIndex的属性,它可以帮助我返回以任何顺序占用的内存。幸运的是,我确信我的内存需求在任何给定时间都不会超过5 MB,所以我可以安全地分配那么多内存。解决。

2 个答案:

答案 0 :(得分:5)

为您提供内存的系统调用是brk。通常的malloccallocrealloc函数只使用brk给出的空格。当该空间不足时,另一个brk用于创建新空间。通常,虚拟内存页面的大小会增加。

因此,如果你真的想拥有预制的对象池,那么请确保以pagesize的倍数分配内存。例如,您可以创建一个4KB的池。 8KB,...空间。

接下来的想法,看看你的对象。其中一些有一个尺寸,一些有其他尺寸。从同一个池处理所有这些分配将是一个巨大的痛苦。为各种大小的对象创建池(最好是2的幂)并从中分配。例如,如果您有一个大小为34B的对象,则可以从64B池中为其分配空间。

最后,剩余空间可以保持未使用状态,也可以向下移动到其他池。在上面的示例中,您剩下30B。您已将其拆分为16B8B4B2B块,并将每个块添加到各自的池中。

因此,您可以使用链接列表来管理预分配的空间。这意味着您的应用程序将使用比实际需要更多的内存,但如果这对您有帮助,为什么不呢?

基本上,我所描述的是来自Linux内核的buddy allocatorslab allocator之间的混合。

编辑:在阅读完您的评论之后,使用malloc(BIG_SPACE)分配一个大区域并将其用作您的记忆池将非常容易。

答案 1 :(得分:1)

如果可以,请查看使用支持此glib memory slicing API的{{3}}。它非常易于使用,使您无需重新实现它。