SGI-STL内存池实现原理

Posted MachineChen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SGI-STL内存池实现原理相关的知识,希望对你有一定的参考价值。

STL之父Alexander Stepanov离开HP之后就去了SGI(Silicon Graphics Computer System, Inc),然后和Matt Austern这些STL大牛一起搞了SGI STL。它也是HP STL的一个继承版本。它属于开放源码,因此你可以修改和销售它。SGI STL被GCC(linux下的C++编译器)所采用,你可以在GCC的Include子目录下找到所有头文件(比如:C:/cygnus/cygwin-b20/include/g++/include)。由于GCC对C++语言标准的支持很好,SGI STL在linux平台上的性能相当出色。此外,其源代码的可读性也很好。可以从如下网站得到更详细的情况介绍:http://www.sgi.com,可以免费下载其源代码。

SGI设计了二级配置机制,第一级配置器直接使用malloc()和free()。当配置区块超过128 bytes时,则采用第一级配置器;否则采用memory pool方式。

memory pool的整体思想是维护128/8 = 16个自由链表,这里的8是小型区块的上调边界。每个自由链表串接的区块大小如下:

序号串连区块大小适用大小
081-8
1169-16
22417-24
15128121-128

下面这幅图主要是空间配置器的框架:

几个过程的思路:

一、申请过程:

if (用户申请的内存不大于128 bytes)   
    查找对应的链表   
    if (对应链表拥有一块以上的区块)   
        调整链表   
        返回第一个区块地址   
    else  
        准备重新填充链表   
            向内存池申请内存(指定数量的区块)   
            if (内存池申请到一个区块)   
                返回第一个区块地址   
            else  
                调整链表,将区块串接起来   
                返回第一个区块地址   
else  
    直接用malloc()申请内存

二、释放过程:

if (用户释放的内存块大于128 bytes)   
    直接用free()释放   
else  
    查找对应的链表   
    回收内存 

三、向内存池申请内存过程:

if (内存池空间完全满足需求量)   
    调整内存池起始位置   
    返回空间地址   
else if (内存池空间不能完全满足需求量,但能提供一个以上的区块)   
    计算能够提供的最大内存   
    调整内存池起始位置   
    返回空间地址   
else  
    从内存池中压缩内存   
    收集比size大的空间   
    递归调用,修正nobjs   
    再次申请内存,可能抛出异常

内存池优缺点:

优点
对于频繁地申请小块内存,减少了申请的时间。

缺点
由于自由链表的内存块大小不连续(8、16、24 …),导致了内部碎片的产生。这使得内存利用率不高。
小块内存释放之后,并没有归还给操作系统,而是放到了自由链表中,会导致系统内存越来越少,除非到程序结束,否则内存不会归还给操作系统。

以上是关于SGI-STL内存池实现原理的主要内容,如果未能解决你的问题,请参考以下文章

SGI-STL简记-内存分配器解析

C++ STL重点难点复习总结

nginx源代码分析之内存池实现原理

内存池的原理及实现

转 内存池技术的原理与实现

内存池