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

Maz*_*yod 4 c memory malloc dynamic-allocation

首先,我从这里得到了这个想法:

曾经有一个我编写的应用程序使用了大量的内存小块,每个都分配了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;
Run Code Online (Sandbox Code Playgroud)

陷阱:

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

灵感来自Mihai Maruseac:

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

Mih*_*eac 5

给你记忆的系统调用是brk.通常的malloccalloc,realloc功能简单地使用所给予的空间brk.当那个空间不够时,另一个空间就会brk产生新的空间.通常,虚拟内存页面的大小会增加.

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

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

最后,剩余空间可以保持未使用状态,也可以向下移动到其他池.在上面的例子中,你已经30B离开了.你会在拆呢16B,8B,4B2B块和每个块添加到各自的游泳池.

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

基本上,我所描述的是来自Linux内核的伙伴分配器slab分配器之间的混合.

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