SGI版的空间配置器解析

本文深入探讨了STL中的空间配置器,包括一级和二级配置器的工作原理。一级配置器简单封装了malloc和free,而二级配置器采用内存池和自由链表策略,有效解决了小块内存分配的碎片问题和性能问题。内存池通过调整分配大小至8的倍数以优化内存利用率,自由链表则加速了内存分配。然而,这种方式可能导致内碎片问题,并且静态的配置器成员可能导致内存占用至程序结束。
摘要由CSDN通过智能技术生成

这篇文章主要介绍的是STL中空间配置器的底层实现。。。 
1、为什么要存在空间配置器? 

为什么要有空间配置器呢?这主要是从两个方面来考虑的。

1、小块内存带来的内存碎片问题

  单从分配的角度来看。由于频繁分配、释放小块内存容易在堆中造成外碎片(极端情况下就是堆中空闲的内存总量满足一个请求,但是这些空闲的块都不连续,导致任何一个单独的空闲的块都无法满足这个请求)。

 

2、小块内存频繁申请释放带来的性能问题。

  关于性能这个问题要是再深究起来还是比较复杂的,下面我来简单的说明一下。

  开辟空间的时候,分配器会去找一块空闲块给用户,找空闲块也是需要时间的,尤其是在外碎片比较多的情况下。如果分配器其找不到,就要考虑处理假碎片现象(释放的小块空间没有合并),这时候就要将这些已经释放的的空闲块进行合并,这也是需要时间的。

  malloc在开辟空间的时候,这些空间会带有一些附加的信息,这样的话也就造成了空间的利用率有所降低,尤其是在频繁申请小块内存的时候。

频繁的申请小额空间,开销非常大。

STL中使用的是空间配置器来解决上面的问题。。。 
2、STL中的空间配置器 
STL中的空间配置器主要分为两级,一级空间配置器(__MallocAllocTemplate)和二级空间配置器(__DefaultAllocTemplate)。 

1>、一级空间配置器 
在SGI版的一级空间配置器中它的Allocate()直接使用malloc,Deallocate()直接使用free,相当于就是对malloc,free做了一层最简单的封装,一级空间配置器还提供了__Malloc_Alloc_OOM_Handler来处理内存不足的情况,如果没有设置此时就会抛出bad_alloc的异常,否则就会循环开辟空间,直到开辟成功才返回。 
一级空间配置器的流程图:

SGI以malloc来配置内存。当malloc()失败后,就调用oom_alloc(),如果客户端没有设置内存不足处理机制,则就直接抛出bad_alloc异常信息,或者直接终止程序。如果客户端设置了内存不足处理机制,则他就会一直调用内存处理机制,企图在某次调用之后获得一块足够的内存。但是如果内存不足处理机制设计不好的话,存在死循环的危险。

直接调用malloc和free来配置释放内存,简单明了。

typedef void(*MALLOCALLOC)();           //将void (*)()   重命名成MALLOCALLOC
/* oom_alloc为静态函数成员,用于处理malloc时的内存不足问题
 _malloc_alloc_handler为静态数据成员,为void(*)()类型的函数指针,用于用户自己制定内存分配策略
	*/
template<int inst>
class _MallocAllocTemplate
{
private:
       static void* _OomMalloc(size_t);       //malloc失败的时候调用的函数
       static MALLOCALLOC _MallocAllocOomHandler;         //函数指针,内存不足的时候的处理机制
public:
       static void* _Allocate(size_t n)                        //分配空间n个字节的空间
       {
              void *result=0;
              result = malloc(n);
              if (0 == result)                    //若果malloc失败,则就调OOM_malloc
                     _OomMalloc(n);
              return result;
       }
       static void _DeAllocate(void *p)                //释放这块空间
       {
              free(p);
       }
	 /*此静态成员函数接受一个void(*)()类型的函数指针作为参数,返回
	void(*)()类型的函数指针。其作用为用用户自己定制的内存调度方法替换
	_malloc_alloc_handler,由此实现类似C++的set_new_handler方法。
	*/

       static MALLOCALLOC _SetMallocHandler(MALLOCALLOC f)    //这是一个函数,参数是一个函数指针,返回值也是一个函数指针
       {
              MALLOCALLOC old = _MallocAllocOomHandler;
              _MallocAllocOomHandler = f;              //将内存分配失败的句柄设置为f(让它指向一个内存失败了,让系统去释放其他地方空间的函数)
              return old;
       }
};
template<int inst>
void(* _MallocAllocTemplate<inst>::_MallocAllocOomHandler)()=0;    //默认不设置内存不足处理机制
template<int inst>
void* _MallocAllocT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值