《STI源码剖析》学习笔记之空间配置器

C++中的new包含两个动作:调用operaotr new分配内存;然后调用构造函数构建对象。delete也包含两个过程:调用析构函数;然后调用operator delete释放内存。
在STL中allocator将这两个动作分开。分配内存由alloc:allocate()负责,释放内存由alloc:deallocate()负责,创建对象由::construct()负责,析构对象由::destroy()负责。

construct(T1*p,const T2&value)
{
    new(p)T1(value);//将初值设置到指针所指的空间上
}
inline voide destroy(T*pointer)
{
    pointer->~T();//将指针所指之物析构,直接调用其析构函数
}
inline void destroy(ForwardIterator first,ForwardIteratot last())
{
__destroy(first,last,value_type(first));//将first到last范围内的所有都析构掉
}

第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区域超过128bytes,视之为足够大,调用第一级配置器;当配置区域小于128bytes,视之为过小,则采用复杂的内存池模式,究竟是采用哪种,取决于__use_malloc().//??
SGI二级空间配置器的做法:如果块足够大,超过128bytes,就由一级空间配置器处理,当快小于128bytes史,以内存池处理。,每次配置一块内存区,并维护对应自由串列,下次若再有相同大小的内存需求,就直接从free-list中取出。如果客户端释放小块内存,则配置器会受到free-list中。SGI会主动将任何小块需求上调至8的倍数,并维护16个free-list,各自管理大小分别为8,16,32,40.。。128bytes的小块区域。
free-list的结构:
union obj
{
union obj*free_list_link;
char client_data[1];
}
由于union的原因,从第一位来看,obj可以被视为一个指针,指向相同形式的另一个obj,从其第二位来看,obj可被视为一个指针,只想内存区块,一物二用。
1: 首先根据用户需求大小,把其调节成8的倍数,然后在16个自由空闲链表中去查找
(((bytes) + __ALIGN - 1) & ~(__ALIGN-1));
2:若找到则把那块从Free_list中分配给用户((bytes + __ALIGN -1) / __ALIGN -1);
3:若恰好找到的那一块是NULL的,则调用refill(ROUND_UP(n))函数,refill函数的意思就是重新填充free_list链表,在STL中规定的是为ree_list为NULL的那块在内存池中选取20块对应大小的内存分配给他,调用chunk_alloc(n,nobjs)函数,当内存池无法满足分配20块的时候则最少就要选取1块分配给他

4:倘若此时内存池中剩下的内存大小比用户所需内存类型的1块还小的时候,则重新开辟池子(使用malloc其大小为:用户所需大小的2倍加上池子以前总大小的十六分之一即:size_t types_to_get =2*total_types + ROUND_UP(heap_size>>4);)

5:若此时开辟失败则在free_list中为NULL的下一块开始选择一块不为NULL的分配给内存池,然后若是成功则递归调用chunk_alloc(n,nobjs)函数

6:若此时还是不可以满足的话则调用一级空间配置器来分配(allocate(types_to_get)函数首先还是会直接调用malloc函数,然后当失败的时候就会调用oo_malloc函数,oo_malloc函数首先会检查my_malloc_handler函数指针是否是NULL,若NULL的话就直接抛出异常,否则调用my_malloc_handler函数(意思是看用户可不可以还一些内存给系统),然后再重新调用malloc函数)
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值