20130331 stl源码剖析之stl分配内存设计
来源:互联网 发布:zabbix 监控域名 编辑:程序博客网 时间:2024/06/05 17:57
本周买了本侯捷的《stl源码剖析》,按照前言所说按顺序阅读下去,感觉stl通篇都是范型的例子,对于C++语言本身来言,我比较不熟的地方就在于虚函数的表,还有就是末班的应用,希望读源码的时候可以丰富关于范型编程的思想。
看完stl的空间适配器一节,感觉大师们写代码所考虑的细节,确实要缜密多了。
1、内存分配与释放、 对象构造与析构的分开
我们都知道,当我们new一个class对象的时候,如下面的例子
class Foo {...};
Foo *p_Foo = new Foo();
new的表达式中包含两个阶段:(1)调用::operator new 配置内存 (2) 调用Foo的构造函数
对于我们来说,这是个正常的现象,甚至与没有办法去改变,stl 源码在这里的处理是:为了精密分工,STL allocate决定将这两个阶段操作分开,内存配置和释放有alloc来完成,对象的构造和析构由::construct() 和 ::destory()负责。 简单来讲就是 内存分配 和对象构造 将不会再一个表达式中完成,这里就需要使用一个新的函数, placement new
(1)placement new
这个是STL ::construct() 使用的函数。 placement new 我会另开一篇博客来讲解,这里先来看下 new 与placement new 的区别
上面已经说了,new 操作有两个步骤,而placement new 则既不分配内存,也不调用其构造函数,它只是指向已经分配好的内存中的某段内存中的指针,这个函数就可以实现stl的想法,把内存分配与释放、 对象构造与析构的分开。
这里顺带说一下STL 析构的一个技巧,析构函数分为trivial 与non-trivial,stl析构函数的参数是一系列的相同类型的对象,万一这个对象很大,且每个析构函数都是无关痛痒的(所谓trivail destruct) ,那么一次次的调用这样的析构函数对效率是一种伤害,所有STL会先判断下这个析构函数的类型,额、、但是C++貌似没有这样的函数,我们接下来看STL是怎样实现它的。
(2)STL 的内存池的设计
STL内存配置设计有以下的特点:
像system heap 要求空间、考虑多线程状态、考虑内存不足的应变措施、考虑过多 小型区域 可能造成的内存碎片问题。
STL设计了两种分配方式,当需要分配的内存大于一个数值时(STL中为128bytes),就直接使用malloc来分配,一旦失败就做一个相应的处理,这个相应的处理可以由客户端来自己设计。
对于第二种分配,当数据小于128bytes时,内存池来分配内存。内存池是这样设计的,主动分配并维护16个freelist(可以看成一个链表),按照8的倍数依次生成16个节点,每次要申请内存的时候,先把要申请的内存的数值换成与8的倍数最靠近的一个节点,然后去该节点下去找是否有足够的空间,如果有直接返回,如果没有的话,先从内存池看是否有至少一个空间。举个例子,如果你申请一个大小为24的空间,而24这个节点刚好没有空间,但是12的节点有两个,内存池就会先把这2个12个空间拿出来返回给客户端,这样就是一个减少碎片空间的例子。也就是说一旦该节点没有内存可以分配了,但是内存池中还有剩余的空间,则将其挂到freelist中去,然后重新分配内次。对于stl来说,释放空间是需要将指针和大小作为参数传过来的。
见过另外一种内存分配机制。它讲空间的大小都是按1024的倍数分成若干份,若用户申请的内存小于1024的倍数,则将其不齐,当内存池不够用的时候,它会先从最大的内存块开始释放,自动释放,为了实现自动释放,它定义了另外一个set map,用来存储所有的分配过得内存,然后从大到小的释放,直到释放的空间足够。
其实这里介绍内存分配的话,如果配上图就更好说明了,可惜图画的不好,以后会专门去学一下画图,如果有不明白的地方或者错误的地方可以发邮件到我邮箱,plyj0123@163.com
希望跟朋友一起分享一起进步
- 20130331 stl源码剖析之stl分配内存设计
- STL源码剖析(一) - 内存分配
- STL源码-内存的分配
- STL源码剖析--内存分配器
- STL源码剖析之STL概述
- STL中vector内存分配策略剖析
- STL之Vector源码剖析
- STL之list源码剖析
- STL之deque源码剖析
- STL之priority_queue源码剖析
- STL 之 pair 源码剖析
- STL 之 vector 源码剖析
- STL 之 deque 源码剖析
- STL 之 list 源码剖析
- STL 之 set 源码剖析
- STL 之 multiset 源码剖析
- STL 之 map 源码剖析
- STL 之 multimap 源码剖析
- Chef学习之五:Knife bootstrap 一台 Ubuntu EC2 机器
- 130324解题报告
- 小鱼儿自动保windwos记事本插件
- 《学习OpenCV》练习题第三章第五题
- C中数组问题--数组作参数与数组长度
- 20130331 stl源码剖析之stl分配内存设计
- 星星等级
- Android应用程序资源的编译和打包过程分析
- Crypto++ 入门(2) AES
- 黑马程序员_Java基础10
- 微软图表控件MsChart使用初探
- Oracle用户密码使用特殊符号,例如&(AND)、$(Dollar)、#(Pound)、*(Star)等
- 《学习OpenCV》练习题第三章第六题
- px与dip、dp换算公式