STL剖析——空间配置器

近来闲来无趣,看了下STL的空间配置器。

首先恭喜我入坑,网上无数的人都在剖析这STL的空间配置器,所以,刚好,今天我也加入了这个团队,这个应该是我目前看到的比较完整架构的一个源码了吧,希望能提示我的水平,毕竟设计的很好。在这里特别说下,没有操作系统的知识,所以在这里的线程和锁的这些问题,我们一概不讨论

STL的空间配置器,就是一个为了给容器进行分配内存和管理内存的东西,容许我盗几张图给大家说明。

这里写图片描述
这个是整个STL的一个结构,后续我会再写博客对这些进行分析。

1.为什么会利用SGI的空间配置器?


首先这个问题具有很强的目的性,因为接触一个东西只有了解了怎么样用才是最快的学习方式之一。
空间配置器而言是对内存管理,所以解决的问题就是内存上的容易出现的问题。所以我们先来看内存上会出现什么问题?

这里写图片描述

这个时候就会出问题了,这个时候就会出现一个外碎片的问题。这个时候的碎片处理方式就可以进行优化,STL当中也就考虑到了这种情况。

另外一个问题就是,对于很多情况下,我们经常会做一些大量的内存分配与释放,比如说在高并发的情况下,但是,在这种情况下,如果你每次都对操作系统进行分配请求与释放请求,这样毫无疑问,效率非常低下,所以,作为提倡效率的一门语言,C++充分的考虑了这个问题。

接下来,就让我们去瞧一瞧。

2.SGI空间配置器的接口

首先我们来看看关于接口部分当我们对一个容器进行new 的时候,在这里提供了一个宏__USE_MALLOC,定义了这个宏,调用第一级配置器,没有定义的,调用第二级配置器。另外就是,接下来,STL 为了让整个符合规范化,在这里,STL封装了一个类叫做simple_alloc,通过这个接口,我们来调用空间配置器进行内存管理。
这里写图片描述

3.SGI空间配置器的一级空间配置器

接下来所说的一级空间配置器,一级空间配置器是一个叫做__malloc_alloc_template的类,首先我们需要知道,只有当在要求分配字节数在128个字节以上的时候这个时候才会去调用一级分配器,这个时候所以简单的也就是采用了malloc和free机制,不过,设计STL的人很聪明,在这为了要求对空间利用的最大化,它在这里还考虑了out of memory机制。

template <int inst>
class __malloc_alloc_template {

private:

static void *oom_malloc(size_t);                            //处理内存不够的函数

static void *oom_realloc(void *, size_t);

#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
    static void (* __malloc_alloc_oom_handler)();           //处理内存不够的一个句柄
#endif

public:

static void * allocate(size_t n)
{
    void *result = malloc(n);                               //进行分配n个内存空间
    if (0 == result)                                        //判断是否分配成功
        result = oom_malloc(n);                             //内存分配不成功,进入OOMMalloc查看是否可以操作系统释放内存分配,如果无法分配,抛出异常。
    return result;                                          

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

static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)
{
    void * result = realloc(p, new_sz);
    if (0 == result) result = oom_realloc(p, new_sz);
    return result;
}

//通过这个函数设置文件句柄,从而间接实现set_new_handler。
static void (* set_malloc_handler(void (*f)()))()
{
    void (* old)() = __malloc_alloc_oom_handler;
    __malloc_alloc_oom_handler = f;             //设置文件句柄
    return(old);                                //返回旧的,操作系统惯用写法。
}

这里我想你就知道了,为什么说new是抛异常了,也会发现这个设计者所做的很好了,尤其是set_new_handler的机制,可以通过这个达到了,对内存的最大利用,当然,new-handler函数需要自己设计,一个好的new-handler函数是非常重要的,否则就非常坑了,关于这里的问题如果不清楚,也可以去参考 effective c++。’
这里写图片描述

4.SGI空间配置器的二级空间配置器


当对象所需内存大于128个字节的时候,这个时候我们就需要去调用第二级空间配置器。
这个时候我们进行维护的就是16个自由链表,这16个自由

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值