pool memory allocate in SGI STL

来源:互联网 发布:centos版本查看 编辑:程序博客网 时间:2024/04/28 04:32

内存的分配和管理一直是C和C++中的重点。

下面就SGI STL中的内存分配技术做一个总结,也算是自己的复习作业。

SGI STL中申请内存时有两级配置器(allocator),第一级是基本的malloc调用系统函数,申请内存。第二级使用了动态链表和内存池技术,减少了与系统的交互,节省了时间,也节省了cookie,仅在每个链表头上有一个cookie,记录链表大小,以便回收时使用。而C++ STL每个获得申请的块区头上都有一个cookie。但是这种技术也存在内存池中占用内存太多,以致影响其他程序运行的弊端(不是内存泄漏,内存池中的内存还可以继续使用,只是没有释放,还给系统)。同时当内存池中内存全部分配完时,还是要调用第一级的malloc。

SGI STL维护16条动态链表,分别标为#0~#15,负责分配#(*+1)× 8bytes(vc和bcc每块大小为4bytes,gcc为8bytes,申请时调整为最接近8的倍数)内存块的分配工作。例如,一个客户需要32bytes内存时,内存池通过第一级malloc调用获得32×20×2 = 1280bytes,其中的32×20bytes由#3号链表维护,并分配第一个块区(32bytes)给客户,(注意:一个链表最多维护20个块区,有时在申请时,由于内存池剩余空闲内存不多,分配给特定编号链表的块区会小于20)。其余的640bytes放在内存池中,以待下次使用。

下次客户再申请内存时,将首先判断内存池中是否够分配

1->将内存池中的内存切成目标大小的块挂接至对应的标号链表,接上例,客户申请64bytes,此时内存池中的内存将会切为640/64 = 10块,挂接在#7号链表下。(注意:这是链表是接着#3号的,所以#7号链表头上没有cookie)

0->调用第一级malloc,再进行分配。此时有两种可能:1.内存池中确实没有内存可供分配。2.内存池中剩余内存无法单独构成客户申请的一个块区,例如:内存池中还有80bytes,客户申请96bytes。这时将剩余内存挂接至对应标号链表,例如将80bytes的块区挂接至#9。

如果客户一直申请内存,直至超过预定的system heap大小,首先将寻找一个适合大小的没有被分配的内存回填至内存池,再按规则进行分配。

如果客户再申请内存,链表中无可用区块,内存池余量又不够一个块区,malloc申请又超过system heap大小,于是失败。但是,此时可能还有尚存的内存没有被使用,而各个链表中亦可能有连续自由块区。

原创粉丝点击