在STL中考虑到小型区块所可能造成的内存碎片问题,SGI STL设计了双层级配置器第一级配置器直接使用malloc()和free();第二级配置器则视情况采用不同的策略:当配置区块超过128bytes 时,则视之为足够大,便调用第一级配置器;当配置区块小于128bytes时,则视之为过小,为了降低额外负担,便采用复杂的内存池的方式来整理,而不再求助于第一级配置器。

<stl_alloc.h>内定义了两个template,一个是 __malloc_alloc_template,这是sgi stl的一级配置器,它的allocate()直接使用malloc()而deallocate()直接使用free(),同时,它模拟C++的 set_new_handler()处理内存不足的状况。

第二个是__default_alloc_template,它维护了16个free list每个list上集合着大小分别为8,16,24,...128大小的内存块。内存池以malloc()配置而得,如果内存不足,转调用第一级配 置器,因为那里设置了内存不足的处理程序。如果请求的内存块大小大于128bytes,就转调用第一级配置器。另外定义了两个alloc,一个是 debug_alloc,每次配置一块内存时,都会配置比需求多8byte的空间以存储空间大小,通过assert语句来检查会不会内存溢出。另一个是 simple_alloc,定义了两个版本的allocate和deallocate,它们都只是单纯的转调用。sgi stl容器全都使用simple_alloc接口。free-list的节点巧妙地使用了一个union结构来管理链表:

    union obj{  union obj* free_list_link;  //当作为自由链表的一个结点时,存储其下一个节点的地址  char client_date[1];        //当其作为返回值时,返回的正好是分配内存的首地址  }  

每次配置器需要向系统要内存的时候,都不是按客户需求向系统申请的,而是一次性向系统要了比需求更多的内存,放在内存池里,有一个free_start和 free_end指示剩余的空间(也就是说内存池剩余的空间都是连续的,因此每次重新向system heap要空间的时候,都会把原先内存池里没用完的空间分配给合适的free list。)当free-list中没有可用区块了的时候,会首先从内存池里要内存,同样,也不是以按客户需求要多少块的,而是一次可能会要上20块,如 果内存池内空间允许的话,可能会得到20个特定大小的内存,如果内存池给不了那么多,那么就只好尽力给出;如果连一个都给不出,那么就要开始向系统即 system heap要空间了。换算的标准是bytes_to_get=2*total_bytes+ROUND_UP(heap_size>>4)。这 个时候使用的是malloc,如果没成功,就尝试着从大块一点的freelist那里要一个来还给内存池,如果还是不行,那么会调用第一级空间配置器的 malloc::allocate,看看out-of-memory机制能做点什么不。

总结起来整个过程大概是这样的,假设我们向系统要x大小的内存,
(1)x大于128byte,用第一级配置器直接向系统malloc,至于不成功的处理,过程仿照new,通过set_new_handler来处理,直到成功返回相应大小的内存或者是抛出异常或者是干脆结束运行;
(2)x小于128byte,用第二级配置器向内存池相应的free_list要内存,如果该freelist上面没有空闲块了,
(2.1)从内存池里面要内存,缺省是获得20个节点,如果内存池中剩余的空间不能完全满足需求量,但足够供应一个(含)以上的区块,则应尽力满足需求。
(2.2) 如果一个都不能够满足的话,则从系统的heap里面要内存给到内存池,换算的标准是 bytes_to_get=2*total_bytes+ROUND_UP(heap_size>>4),申请的大小为需求量的两倍加上一个 附加值,如果内存池中还有剩余的内存,则将残余零头分配给适当的free list,这时使用的是系统的malloc,如果要不到:
(2.3)从比较大的freelist那里要内存到内存池,如果还是要不到:
(2.4) 从系统的heap里面要内存给到内存池,换算标准跟2.2一样,但是这时候使用的是第一级配置器的allocate,主要是看看能不能通过 out_of_memory机制得到一点内存。所以,freelist总是从内存池里要内存的,而内存池可能从freelist也可能从系统heap那里 要内存。
SGI STL的alloc的主要开销就在于管理这些小内存,管理这些小内存的主要开销就在于,每次freelist上的内存块用完了,需要重新要空间,然后建立 起这个list来。freelist上的内存,会一直保留着直到程序退出才还给系统。但这不会产生内存泄漏,一来是管理的都是小内存,二来是,占用的内存 只会是整个程序运行过程中小内存占用量最大的那一刻所占用的内存。


转载于:https://www.cnblogs.com/LUO77/p/5824625.html

SGI STL 内存分配方式及malloc底层实现分析相关推荐

  1. C/C++ 内存分配方式,堆区,栈区,new/delete/malloc/free

    内存分配方式有三种: [1] 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量, static 变量. [2] 在栈上创建.在执行函数时,函数内局 ...

  2. C/C++:程序的内存分配方式

    转载自:http://ryansky.blog.51cto.com/187974/86286 1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内 ...

  3. C/C++内存分配方式 .

    1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...

  4. C语言程序的内存分配方式

    1.内存分配方式  内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数 ...

  5. 内存分配方式以及堆和栈的区别

    转载:https://blog.csdn.net/shanchangyi/article/details/51854795 对于一个程序要运行,涉及到的内存分配是一个首要问题,这里简单说一下一个简单的 ...

  6. 内存分配详解 malloc, new, HeapAlloc, VirtualAlloc,GlobalAlloc

    很多地方都会使用内存,内存使用过程中操作不当就容易崩溃,无法运行程序,上网Google学习一下,了解整理下他们之间的区别以及使用 ,获益匪浅 0x01 各自的定义和理解 (1)先看GlobalAllo ...

  7. C++内存分配方式、内存错误及其对策

    C++内存分配方式.内存错误及其对策 内存分配方式有三种: 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. 在栈上创建.在执 ...

  8. C++中内存分配方式、空指针及野指针的区别

    一.C++中内存分配方式可以分为三种: (1)从静态存储区域分配: 内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在.速度快.不容易出错,因为有系统会善后.例如全局变量,static变 ...

  9. MFC 教程【10_内存分配方式和调试机制 】

    内存分配方式和调试机制 M内存分配 内存分配函数 MFCWin32或者C语言的内存分配API,有四种内存分配API可供使用. Win32的堆分配函数 每一个进程都可以使用堆分配函数创建一个私有的堆── ...

最新文章

  1. 64位win7安装vs2010出现“组件安装失败...”等问题的解决方法
  2. gff文件_GFF格式说明
  3. 移动端实现PDF文件阅读的方法
  4. 边缘链接 matlab,matlab-“简单”边缘-线-检测
  5. 【Python】学习笔记总结2(Python面向对象)
  6. Android之在linux环境不通过TAG快速过滤日志
  7. python模块:运行机制与编写方法
  8. iOS - CALayer 绘图层
  9. python的命名空间_python命名空间(namespace)
  10. Mac系统下不能直接往移动硬盘里面拷贝东西,用Mounty之后硬盘打不开,怎么办?
  11. 商汤科技面试——实习面试案例总结
  12. virtualbox虚机无法上网
  13. SpringBoot 项目修改html后不需要重新启动(热部署)
  14. C# PDF附件生成
  15. 插入摄像头时,系统右下角提示:无法识别的USB设备:跟这台计算机连接的一个USB设备运行不正常...
  16. Python自动化测试框架
  17. javascript利用iframe打印pdf文档失败的问题
  18. 计算机硬件信息被修改怎么还原,修改bios硬件信息方法
  19. java创建response对象_创建一个HttpResponse对象
  20. Java岗定级阿里P6-二面蚂蚁金服(交叉面),已拿offer

热门文章

  1. 理解学习率以及如何提升深度学习的性能
  2. 一句话总结贝叶斯分类器
  3. seq2seq中的beam search算法过程
  4. 特约专栏丨孙茂松教授——自然语言处理一瞥:知往鉴今瞻未来
  5. 碰疼了会躲!这个植入“迷你大脑”的AI机器人,可感知疼痛,还能自我愈合...
  6. 沃丰报告:物联网的未来
  7. 理论计算机科学中最令人困惑的谜题之一被解开
  8. 学习新技能时,大脑在如何发生改变?
  9. 深入卷积神经网络背后的数学原理
  10. 2018-2019年新一代AI领域十大最具成长性技术展望