STL读书笔记(一)

  SGI 空间分配器具备次分配能力。

  第一级配置器以malloc(),free(),realloc(),等C函数执行实际的内存配置、释放、重配置操作,并实现出类似C++ new handler的机制,是的,它不能直接运用C++ new handler机制,因为它并非使用::operator new 来配置内存。

  所谓C++ new handler机制是,你可以要求系统在内存配置需求无法被满足要求时,调用一个你所指定的函数,换句话说,一旦::operator new 无法完成任务,在丢出std::bad alloc 异常状态之前,会先调用由客户端指定的处理历程。该处理历程通常即被称为new-handler。new handler解决内存不足的做法有特定的模式。

  注意,SGI以malloc()而非::operator new 来配置内存(我所能够想到的一个原因是历史因素,另一个原因C++并未提供相当于realloc()的内存重置操作,因此C++不能直接使用C++的set_new_handler(),必须仿真一个类似的set_malloc_handle())。

  第一次配置器比较简单,类似于C语言的malloc();

  第二级配置器的做法是,如果区域够大,超过128Bytes,就移交第一级配置器处理。当区块小于128Bytes时,则以内存池(memory poll)管理,此法又称为次层配置:每次配置一大块内存,并维护对应之自由链表(free list)。下次如果再有相同大小的内存需求,就直接从free list取出。如果客端释放小额区块,就由配置器回收到free list中,是的,别忘了,配置器除了负责配置,也负责回收。为了方便管理,SGI第二级配置器会主动将任何小额区块的内存需求量上调至8的倍数(例如客端要求30Bytes,就自动调整为32Bytes)并维护16个free lists,各自管理大小分别为8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128Bytes的小额区块。free list的节点结构如下:

  union obj{

    union obj* free_list_link;

    char client_data[1];

}


  你们或许会想,为了维护链表(lists),每个节点需要额外的指针(指向下一个节点),这不又造成另一种额外负担吗?你的顾虑是对的,但早已有好的解决办法。注意,上述obj所用的是union,由于union之故,从第一字段观之,obj可被视为一个指针,指向相同形式的另一个obj。从第二个字段观之,obj可被视为一个指针,指向实际区块。一物二用的结果是,不会为了维护链表锁必须的指针而造成一种内存浪费的(我们正在努力节省内存的开销呢),这种技巧在强型转换语言中java不行,但是在非强行语言如C++十分普遍。

猜你喜欢

转载自blog.csdn.net/wujiafei_njgcxy/article/details/78314018