阅读了SGI的源码后对STL很是膜拜,很高质量的源码,从中学到了很多。温故而知新!下文中所有STL如无特殊说明均指SGI版本实现。

STL 内存配置器

STL对内存管理最核心部分我觉得是其将C++对象创建过程分解为构造、析构和内存分配、释放两类操作分离开来!摆脱了对频繁调用new或malloc函数想操作系统申请空间而造成的低效。其中析构操作时对具有non-trival、trival 析构函数的class区别对待也提高了效率。SGI 的两级配置器结构属于锦上添花。

STL内存配置器有没有内存泄漏?

STL两级结构的配置器使得STl能对小的空间内存分配管理更为合理,而很多人有疑问的时这个对小空间的配置器是否存在内存泄漏?“源码面前了无秘密”问题来于源码自,答案也在源码之中。先概述一下STL两级结构的配置器是怎么操作的,STL的Allocator中队内存的申请和释放均是通过其两个静态成员函数完成,allocate,deallocate;对于大于128Byte的内存申请和释放,两个函数均通过调用malloc和free来实现。当内存不大于138Byte时,该allocator会通过一个链表和内存池来维护空间。很多人疑惑为什么在该Allocator的实现里只有对内存池malloc的代码,没看到类似free这样释放内存的代码,甚至该Allocator类都没有析构函数,这样不是会存在内存泄漏吗?其实不然,对于由链表维护的内存,其内存的释放工作应该是上一层调用者负责,比如容器Vector在析构函数中就显示的将其申请的所有capacity大小的内存释放。内存池则不一样,内存池的中的内存将会一直保留知道程序退出。有的同学可能会认为“这不就是内存泄漏吗?比如一个创建了一个Vector变量,到Vector析构了之后再内存中竟然有一块内存没有被系统回收,这不就是内存泄漏吗”,其实不然:

1. 申请的内存没有被及时释放不等于内存泄漏

在单线程中,由于该Allocator中记录内存池起始的指针是静态类型,所以只要是你在同一个线程中,无论你创建多少个Allocator,记录内存池的变量都是同一个,换句话说,当下次再创建Vector时,还是使用上一次使用的那个。

2. 该内存池不会疯狂野生长

这个内存池的空间其实是很小的,因为大于128Byte的内存申请都直接转调了malloc,从源码中也可以看出,内存池每次重新灌水的新容量是2*total_size + round_up(heap_size >> 4)。

内存池的存在是为了避免大量内存碎片的产生,代价是管理内存所需要多付出的时间和空间消耗。

以上就是内存池一种存在直至程序退出的原因。

在GCC 5.4.0 中的使用的SGI已经对该种设计做了大幅修改。1. 默认的Allocator也不在是侯捷一书中说指出的具有内存池的配置器,而是"\usr\include\c++\5\ext\new_allocator.h"其实现直接调用new;2. 而之前相应的具备内存池的配置器则被当做STL的扩展,实现于"\usr\include\c++\5\ext\pool_allocator.h"中,且该实现不在存在内存池的设计,只保留了使用链表将小内存块连接起来的设计(使用时记得include该文件路径,命名空间为__gnu_cxx::__pool_alloc<int> )。

在llvm中Allocator的实现也是直接调用new。

FYI:

GCC更换Allocator设计,http://www.cppblog.com/peakflys/archive/2015/01/14/209513.html

SGI源码,https://www.sgi.com/tech/stl/download.html

SGI源码,allocator,https://www.sgi.com/tech/stl/stl_alloc.h

SGI源码,vector,https://www.sgi.com/tech/stl/stl_vector.h

最新文章

  1. 使用MonoTouch.Dialog简化iOS界面开发
  2. 【项目管理】图解GitHub基本操作
  3. 真有用?Snap和Flatpak 通吃所有发行版的打包方式。
  4. atitit.木马病毒webshell的原理and设计&#160;java&#160;c#&#160;.net&#160;php.
  5. DP ZOJ 3872 Beauty of Array
  6. compiler
  7. Tomcat漏洞说明与安全加固
  8. HDU 3333 &amp; 3874 (线段树+离线询问)
  9. nginx_笔记分享_php-fpm详解
  10. Cocos2d—X游戏开发之CCTableView详解(十一)
  11. IT资源专业搜索-www.easysoo.cn
  12. Python内置函数(45)——ascii
  13. javascript之prototype原型属性案例
  14. Linux驱动之输入子系统简析
  15. sublime3安装ctags追踪插件
  16. redis的数据类型命令
  17. turret
  18. BurpSuite中的安全测试插件推荐
  19. python 统计学的各种检验
  20. cacti安装spine 解决WARNING: Result from CMD not valid. Partial Result: U错误

热门文章

  1. 单页面应用(spa)引入百度地图(Cannot read property &#39;dc&#39; of undefined)
  2. js中this的指向总结
  3. Restful接口调用方法超详细总结
  4. Tornado session 插件 pycket 定制时间和时间续租
  5. ps 命令的详细功能解析
  6. CSharpGL(44)用ShadowMapping方式画物体的影子
  7. css小随笔(二)与通用样式
  8. vue的一些坑(第二天)
  9. RabbitMQ 使用(一)
  10. RabbitMQ教程(一)——安装配置