STL源代码剖析(一) - 内存分配
Allocaor
allocator 指的是空间配置器,用于分配内存。
STL中默认使用SGI STL alloc作为STL的内存分配器,尽管未能符合标准规格,但效率上更好。
SGI STL也定义有一个符合标准,名为allocator的配置器,但SGI自己从未使用过它,主要原因是它仅仅把C++的new操作符和delete操作符做了一层薄薄的封装。
C++的new操作符和delete操作符进行内存配置时,new:先配置内存,然后构造对象。delete:先析构对象,然后释放内存。SGI STL将内存配置、释放内存与构造、析构分开。前者由<stl_alloc.h>中的allocate()和deallocate()负责,后者由<stl_construct.h>中的construct()和destroy()负责。 这两个头文件包括于<memory>中(STL标准规定,配置器定义在memory中)。同一时候<memory>还包括了一个文件<stl_unitialized.h>,定义了一些全局函数用来填充、复制大块内存数据。
STL allocator中,alloc::allocate负责内存配置,alloc::deallocate负责内存释放,alloc::construct负责对象构造,alloc::destroy负责对象析构。
SGI对空间的配置与释放的设计哲学:
1.向system heap要求空间;
SGI底层用的malloc和free完毕内存的配置和释放。
2.考虑多线程状态;
3.考虑内存不足时的应变措施;
4.考虑过多“小型区块”可能造成的内存碎片问题。
SGI设计了双层级配置器,第一级直接使用malloc和free,第二级配置器则视情况採用不同的策略:当配置区块超过128bytes时,视之为“足够大”,调用第一级配置器,当小于128bytes时,视之“过小”,为了减少额外负担,便採用复杂的memory pool方式,不再求助于第一级适配器。
一二级配置器关系例如以下
第一级配置器以malloc(),free(),realloc()等c函数运行实际的内存配置,释放,重配置操作,并实现相似 C++ new handler的机制(不能使用C++ new handler的原因时它并不是使用operator new 来配置内存)。
小额区块带来的事实上不仅时内存碎片,配置时的额外负担也是一个大问题,额外负担无法避免。
第二层配置器:假设区块勾搭,超过128bytes时,就移交第一层配置器处理,当区块小于128bytes时则以内存池管理。
内存基本处理工具
STL定义的五个全局函数
construct() - 构造
destroy() - 析构
uninitialized_copy(),uninitialized_fill(),uninitialized_fill_n() - 范围拷贝构造
关于拷贝构造的三个函数,可以将内存的配置与对象的构造行为分离。假设作为输入目的地的[result, result + (last-first)]范围内的每个迭代器都指向未初始化的区域,则uninitialized_copy()使用copy constructor,将输入来源范围内每个对象产生一份复制品,放进输出范围中。
容器的全区间构造函数通常以两个步骤完毕:
1.配置内存区块,是以包括范围内的全部元素;
2.使用uninitialied_copy(),在该内存区块上构造元素。
它们负责在已分配好的空间进行构造。C++标准要求uninitialized_copy具有"commit or rollback"语义:要么做完,要么不做。
在详细的实现中,这三个函数也用到了traits技法,通过traits萃取出元素的特性,假设是POD(Plain Old Data)型别,说明其拥有trivial ctor/ dtor/ copy/ assignment函数,因此可以使用copy()、fill()、fill_n()等算法,假设不是POD型别就仅仅可以循环调用construct()函数了。
參考
<<STL源代码剖析>> 侯捷译
STL源代码剖析(一) - 内存分配的更多相关文章
- 《STL源代码剖析》---stl_deque.h阅读笔记(2)
看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque. ...
- STL源代码剖析 读书总结
<<STL源代码剖析>> 侯捷著 非常早就买了这本书, 一直没看, 如今在实验室师兄代码的时候发现里面使用了大量泛型编程的内容, 让我有了先看看这本书的想法. 看之前我对于泛型 ...
- STL源代码剖析——STL算法stl_algo.h
前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...
- STL源代码剖析——基本算法stl_algobase.h
前言 在STL中.算法是常常被使用的,算法在整个STL中起到很关键的数据.本节介绍的是一些基本算法,包括equal.fill.fill_n,iter_swap.lexicographical_comp ...
- STL源代码剖析——STL算法之set集合算法
前言 本节介绍set集合的相关算法,各自是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference.这 ...
- STL源代码剖析(二) - 迭代器与traits技法
提要 先看一段用迭代器的代码: int a[] = {1, 2, 3, 4, 5}; vector<int> v1( a, a+5); vector<int>::iterato ...
- 《STL源代码剖析》---stl_alloc.h阅读笔记
这一节是讲空间的配置与释放,但不涉及对象的构造和析构,仅仅是解说对象构造前空前的申请以及对象析构后空间怎么释放. SGI版本号的STL对空间的的申请和释放做了例如以下考虑: 1.向堆申请空间 2.考虑 ...
- 解析STL中典型的内存分配
1 vector 在C++中使用vector应该是非常频繁的,但是你是否知道vector在计算内存分配是如何么? 在c++中vector是非常类似数组,但是他比数组更加灵活,这就表现在他的大小是可以自 ...
- STL 源代码剖析 算法 stl_algo.h -- inplace_merge
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) ----------------------- ...
随机推荐
- hdu4185+poj3020(最大匹配+最小边覆盖)
传送门:hdu4185 Oil Skimming 题意:n*n的方格里有字符*和#,只能在字符#上放1*2的板子且不能相交,求最多能放多少个. 分析:直接给#字符编号,然后相邻的可以匹配,建边后无向图 ...
- poj 2166 构造
一个看了解题报告才能想明白的题目,第一点比较容易想明白,就是每次把1交换到堆顶之后如果能够换到最后面的位置那么一定是最优的,但是怎么实现这个没有想明白. 题解的那种构建方法,及从2开始插入,是可以保证 ...
- Visual Prolog 的 Web 专家系统 (8)
GENI核心 -- 推理引擎(2)流量控制 1.阐述fail."!"而回溯 与其他语言相比,,Prolog最大的特点.这是回溯机制. 回溯机制,还有的主要手段2个月,首先,通过使用 ...
- BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MB Submit: 185 Solved: 94 [ Submit] ...
- [置顶] quartznet任务调度和消息调度(JAVA与C#版对比)
quartznet任务调度和消息调度 1. 作用 自动执行任务. 2. 下载地址 NET版本 JAVA版本 1下载 http://quartznet.sourceforge.net/downloa ...
- Radmin远程控制软件
Radmin远程控制软件 日期:2015-08-20 作者:lujl Radmin是一款快速的远程控制软件,可以用来远程管理公司或个人计算机来实现远程办公.你可以通过鼠标和键盘来控制远程的 ...
- JAVA命令参数详解
JAVA命令参数详解 JAVA命令详解 结构 说明 Java 和 OldJava JIT 选项 另请参阅 结构 java [ options ] class [ argument ... ] java ...
- DIV 居中对齐
<div style="text-align:center;margin-right:auto;margin-left:auto">
- C++结构体:默认构造函数,复制构造函数,重载=运算符
C++结构体提供了比C结构体更多的功能,如默认构造函数,复制构造函数,运算符重载,这些功能使得结构体对象能够方便的传值. 比如,我定义一个简单的结构体,然后将其作为vector元素类型,要使用的话,就 ...
- eclipse加入辅助线,配合代码格式化使用