stl源码剖析_STL源码剖析——allocator分配器(下)

dd20084c60f4106669bf14487e57e960.png

写在前面

上篇文章写了如何实现一个简易的 allocator 空间配置器,这篇文章来讲讲 allocator 空间分配的内部机制

由于分配过多的“小型区块”会造成内存碎片问题,SGI 设计了双层级配置器,即第一级配置器第二级配置器

f5ec1013d0491b235bed1daacc016a99.png图1 第一级配置器与第二级配置器

第一级配置器

第一级配置器以 malloc(),free(),realloc() 等 C 函数执行实际的内存配置、释放、重配置操作。

如图 1 第一级配置器部分所示,部分代码如下:

template <int inst>
class __malloc_alloc_template {  // 第一级配置器
......  // 省略部分细节代码

static void * allocate(size_t n){
    void *result = malloc(n);   // 第一級配置器直接使用 malloc()
    if (0 == result) result = oom_malloc(n);
    return result;
}

static void deallocate(void *p, size_t /* n */){
    free(p);    // 第一級配置器直接使用 free()
}

static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz){
    void * result = realloc(p, new_sz); // 第一級配置器直接使用 realloc()
    if (0 == result) result = oom_realloc(p, new_sz);
    return result;
}

......  // 省略部分细节代码
};

第二级配置器

第二级配置器视情况采用不同的策略:当配置区块超过 128 bytes 时,视之为“足够大”,便调用第一级配置器;当配置区块小于 128 bytes 时,视之为“过小”,为了降低额外负担,便采用内存池配置方式。

在往下看之前,我们先来聊聊 “cookie” 这个概念。

如图 2 所示,cookie 如同分配内存的“身份证”,用来记录内存大小的信息。

它所占分配内存的大小是不变的,当所需内存越小,cookie 所占整个分配内存的比例就越大,操作系统维护这块内存造成的损耗就越大;反之,操作系统维护这块内存造成的损耗就越小。

1e06901563e41abf18047bd1868a5c0a.png图2 cookie

当配置区块小于 128 bytes 时,我们视之为小内存,按照以上说法操作系统维护这块内存造成的损耗就会比较大。

再者,操作系统分配内存并不是按照地址顺序一个接着一个内存分配的,它是哪里有合适的大小就取哪里的内存,这种东取一块西取一块就会造成大量的内存碎片。

那有什么方法来解决上面的问题呢?

为了解决以上的难题,第二级配置器解决的方法就是,每次都给内存池中申请一大块的内存空间,并且用多条自由链表对这块内存进行维护

81a78dd4fb9f440c168cf57b506c457a.png图3 第二级配置器
1. 自由链表
每次配置一大块内存,就直接从自由链表的表头拨出。如果释放小额区块,就由配置器回收到自由链表表头。 为了方便管理,第二级配置器会主动将任何小额区块的内存需求量上调至 8 的倍数,并维护 16 个自由链表,各自管理大小分别为 8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128 bytes 的小额区块。
2. 内存池
内存池是在真正使用内存之前,预先申请分配一定数量、大小相等(一般情况下)的内存块留作备用。 当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是,使得内存分配效率得到提升。

最后

最后的最后,千言万语不如一图明了。。。

55f90105ed69986dd7c2a69e147df942.png

allocator 整体框架图
如果这篇内容对你有帮助,可以点个在看支持一下。同时,欢迎关注下方微信公众号『编程异思坊』,更多精彩内容等你探索!

eb60e2d2ae722824f4e6d09f1efa4290.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值