STL中内存配置时的设计哲学如下:
- 向system heap要求空间
- 考虑多线程(multi-threads)的状态
- 考虑内存不足时的应变措施
- 考虑过多“小型区块”可能造成的内存碎片(fragment)问题
解决方法如下:
- SGI以mallco()和free()完成内存的配置及释放
- 考虑“小型区块”造成的内存破碎问题:SGI设计了双层级配置器
双层级配置器:当索取的内存块>128bytes时,移交第一级配置器,当<128bytes时,则以内存池(memory pool)管理:SGI第二级配置器会主动将任何小额区块的内存需求量上调至8的整数倍,并维护16个free-list,各自管理大小分别为(8,16,24,32,40…128)
free-list的节点结构如下:
union obj{
union obj* free_list_link;
char client_data[1]; //1是举例值,可以为8,16,...,128
};
由类型”union”可知指针free_list_link和数组client_data共享一段大小为sizeof(union obj)=4的内存空间。当指针free_list_link指向下一个节点时,client[0]内存储的内容为下一个节点的前一个字节大小的地址(实际上,现在数组client_data并没有使用到)。但当客端需要使用小额区块,即使用client_data数组的时候,free_list_link内存储的下一个节点的地址数据将被覆盖掉,故而free-list也就不再指向他们。
这时就实现了一物两用的目的。
考虑内存不足时的应变措施
当free-list中没有可用区块的时候,调用refill()重新为free-list填充空间,新的空间将取自内存池(经由chun_alloc完成),取得缺省的20个新节点,如果内存池空间不足,获得的新节点数量可能小于20个。
流程如下: