Tenshi的函数接口

Tenshi的内存池算法

太阳神上 posted @ 2008年4月11日 15:23 in Tenshi with tags Tenshi , 1508 阅读

  作为一个解释器的语言,大量的小尺寸的对象需要频繁地申请和释放,这样一来,如果只是仅仅地使用C语言标准库的malloc和free来申请和释放,势必会大大地影响效率。于是我想到了内存池,这样对于小对象的申请和释放就可以大大提高,我在搜索网上的相关算法,找到了一个AutoFreeAlloc,是所谓的C++的GC,看完后,觉得并不是一个真正的GC,只不过对于小尺寸的对象可以比一般的new更好,就其特性而言,似乎是一个通过申请堆空间来实现一个栈,在一个使用它的局部过程里,多次申请,一次释放。
  那里面的算法虽然不大符合我的要求,但思想很简单,很有启发性。于是我在此基础上,再加上了一自己的释放部分的算法,形成了一个简单的内存池系统。
  在这个内存池中,主要有两个静态对象,一个叫Allocator,它是一个结构体,内部有prev,begin和end三个void *型的指针,这个对象一开始指向一个静态数组,prev为NULL,begin为这个静态数组的头部,而end为静态数组的尾部,整个静态数组的大小为BLOCKSIZE,定义为2048,也就是2k,小于这个大小的内存我们认为是小内存。
  另外一个静态对象叫就Collector,一旦从内存池free掉,就可以立刻挂到这个Collector上来,Collector是一个有12个元素的数组,其中前面三个不用,事实上起用的是从第4个开始的,也就是只有Collector[3]~Collector[11]能用,例如说要释放掉一个256个字节的对象,256是2的8次幂,就么就挂到Collector[8]上面去。
  申请空间的步骤如下:先计算其以2为底的对数,若大于12,说明这不是小内存,直接用malloc申请;如果对应的Collector已有回收的对象,则优先使用Collector中的对象,如果没有的话就到Allocator里去找。
  Allocator主要控制大小为BLOCKSIZE的内存块,其中end-begin的大小就是这个内存块的空间大小,如果申请的大小小于当前的空闲空间,就只要把end提前就可以了,然后把这段提前的空隙返回,如果这块不够,则再申请一块内存,大小仍为BLOCKSIZE,然后再重新设置Allocator,使之管理这块新的内存,并同时把这些新的内存的一部分返回。
  内存池释放时,只需要依次遍历内存块释放之就可以了。Collector不用管,因为它收集的都是原来内存块的内容,一旦所有的内存块释放,它所管理的内存块也就全部释放了。
 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter