空间适配器是 所有组件的核心
每个操作系统都有自己的内存分配器
他承担着内存分配 管理 释放
作为模版参数传递到每个容器去
allocate函数分配一片连续的未被构造的空间备用,
deallocate 函数释放空间
construct函数调用布局new,同时调用构造函数,对象被new定位在指定位置
destory 函数调用析构函数,
适配器分一级和二级
第一级适配器剖析:
第一级配置器以malloc() free() remalloc() 等C函数执行实际的内存配置 释放 重配置操作 并实现出类似
C++ new-handler的机制 这里并没有直接使用C++ new-handler机制 (没有使用::operator new来配置内存)
SGI第一级配置器的allocate()和remalloc()都是在调用malloc()和remalloc() 不成功之后 改调用oom_malloc() 和
oom_realloc() 后两者都有内循环,不断调用 ‘内存不足处理例程’,期望在某次调用之后获得足够的内存而圆满
完成任务。若内存不足,会抛异常,异常处理应该提前设定。
但是如果‘内存不足处理例程’没有被设定当内存不足时直接抛出‘__THROW_BAD_ALLOC’ 丢出bad_alloc异常信息。
第二级适配器剖析:
SGI第二级配置器的做法是:如果区块够大,超过128bytes时就移交第一级配置器处理。当区块小于128bytes时
则以内存池管理:每次配置一大块内存,并维护对应的自由链表;下次若再有内存需求,直接从free list中取。
如果使用者释放了小额区域 就由配置器会收到free-list。为了方便管理,SGI第二级适配器会主动将任何小额区块内存需求上调至8的倍数。
为了维护自由链表 每一个节点都需要额外的指向下一个节点的指针,这对于频繁使用的类库来说,必须锱铢必较。
于是此处有了一个好的解决方案:union联合类型
union obj{
union obj* free_list_link;
char client_data[1];
};
当用户没有申请内存时 free_list_link有效指向下一个节点
当用户申请了内存时 client_data有效 指向内存首地址
同一时间只有一个value有效正是union的特点。
这种技巧在强类型语言JAVA中不会出现,但是在非强行语言C/C++中十分普遍
另 在LUA源码中看到过储存变量也是使用union Lua的变量能相互转化也是基于词机制
参考:
http://blog.csdn.net/effective_coder/article/details/8991980
http://www.voidcn.com/blog/hujian_/article/p-5807328.html