常见C++内存池技术
总结下常见的C++内存池,以备以后查询。
应该说没有一个内存池适合所有的情况, 根据不同的需求选择正确的内存池才是正道.
(1)最简单的固定大小缓冲池
适用于频繁分配和释放固定大小对象的情况, (2)dlmalloc
应该来说相当优秀的内存池, 支持大对象和小对象,并且已被广泛使用。到这里下载:ftp://g.oswego.edu/pub/misc/malloc.c
关于dlmalloc的内部原理和使用资料可以参考:内存分配器dlmalloc 2.8.3源码浅析.doc(3) SGI STL 中的内存分配器( allocator )
SGI STL 的 allocator 应该是目前设计最优秀的 C++ 内存分配器之一了,它的运作原理候捷老师在《 STL 源码剖析》里讲解得非常清楚。基本思路是设计一个 free_list[16] 数组,负责管理从 8 bytes 到 128 bytes 不同大小的内存块( chunk ),每一个内存块都由连续的固定大小( fixed size block )的很多 chunk 组成,并用指针链表串接起来。比如说
free_list[3]->start_notuse->next_notuse->next_notuse->...->end_notuse;
当用户要获取此大小的内存时,就在 free_list 的链表找一个最近的 free chunk 回传给用户,同时将此 chunk 从 free_list 里删除,即把此 chunk 前后 chunk 指针链结起来。用户使用完释放的时候,则把此chunk 放回到 free_list 中,应该是放到最前面的 start_free 的位置。这样经过若干次 allocator 和 deallocator 后, free_list 中的链表可能并不像初始的时候那么是 chunk 按内存分布位置依次链接的。假如free_list 中不够时, allocator 会自动再分配一块新的较大的内存区块来加入到 free_list 链表中。
可以自动管理多种不同大小内存块并可以自动增长的内存池,这是 SGI STL 分配器设计的特点。
(4) Loki 中的小对象分配器( small object allocator )
Loki 的分配器与 SGI STL 的原理类似,不同之处是它管理 free_list 不是固定大小的数组,而是用一个 vector 来实现,因此可以用户指定 fixed size block 的大小,不像 SGI STL 是固定最大 128 bytes 的。另外它管理 free chunks 的方式也不太一样, Loki 是由一列记录了 free block 位置等信息的 Chunk 类的链表来维护的, free blocks 则是分布在另外一个连续的大内存区间中。而且 free Chunks 也可以根据使用情况自动增长和减少合适的数目,避免内存分配得过多或者过少。
(5) Boost 的 object_pool
Boost 中的 object_pool 也是一个可以根据用户具体应用类的大小来分配内存块的,也是通过维护一个 free nodes 的链表来管理的。可以自动增加 nodes 块,初始是 32 个 nodes ,每次增加都以两倍数向 system heap 要内存块。 object_pool 管理的内存块需要在其对象销毁的时候才返还给 system heap 。
(6)ACE 中的 ACE_Cached_Allocator 和 ACE_Free_List
ACE 框架中也有一个可以维护固定大小的内存块的分配器,原理与上面讲的内存池都差不多。它是通过在 ACE_Cached_Allocator 中定义个 Free_list 链表来管理一个连续的大内存块的,里面包含很多小的固定大小的未使用的区块( free chunk ),同时还使用 ACE_unbounded_Set 维护一个已使用的 chuncks ,管理方式与上面讲的内存池类似。也可以指定 chunks 的数目,也可以自动增长,定义大致如下所示:
class ACE_Cached_Allocator : public ACE_New_Allocator<T> {
public:
// Create a cached memory pool with @a n_chunks chunks
// each with sizeof (TYPE) size.
ACE_Cached_Allocator(SIZET n_chunks = ACE_DEFAULT_INIT_CHUNKS);
T* allocate();
void deallocate(T* p);
private:
// List of memory that we have allocated.
Fast_Unbounded_Set<char *> _allocated_chunks;
// Maintain a cached memory free list.
ACE_Cached_Free_List<ACE_Cached_Mem_Pool_Node<T> > _free_list;
};
Google的开源项目gperftools, 主页在这里:https://code.google.com/p/gperftools/,该内存池也被大家广泛好评,并且在google的各种开源项目中被使用, 比如webkit就用到了它。
常见C++内存池技术的更多相关文章
- Netty精粹之轻量级内存池技术实现原理与应用
摘要: 在Netty中,通常会有多个IO线程独立工作,基于NioEventLoop的实现,每个IO线程负责轮询单独的Selector实例来检索IO事件,当IO事件来临的时候,IO线程开始处理IO事件. ...
- 内存池技术(UVa 122 Tree on the level)
内存池技术就是创建一个内存池,内存池中保存着可以使用的内存,可以使用数组的形式实现,然后创建一个空闲列表,开始时将内存池中所有内存放入空闲列表中,表示空闲列表中所有内存都可以使用,当不需要某一内存时, ...
- Linux服务器内存池技术是如何实现的
Linux服务器内存池技术是如何实现的
- boost::pool与内存池技术
建议看这个链接的内容:http://cpp.winxgui.com/cn:mempool-example-boost-pool Pool分配是一种分配内存方法,用于快速分配同样大小的内存块, ...
- 内存分配(new/delete,malloc/free,allocator,内存池)
以下来源http://www.cnblogs.com/JCSU/articles/1051826.html 程序员们经常编写内存管理程序,往往提心吊胆.如果不想触雷,唯一的解决办法就是发现所有潜伏的地 ...
- nginx——内存池篇
nginx--内存池篇 一.内存池概述 内存池是在真正使用内存之前,预先申请分配一定数量的.大小相等(一般情况下)的内存块留作备用.当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续 ...
- Linux简易APR内存池学习笔记(带源码和实例)
先给个内存池的实现代码,里面带有个应用小例子和画的流程图,方便了解运行原理,代码 GCC 编译可用.可以自己上网下APR源码,参考代码下载链接: http://pan.baidu.com/s/1hq6 ...
- 初识nginx——内存池篇
初识nginx——内存池篇 为了自身使用的方便,Nginx封装了很多有用的数据结构,比如ngx_str_t ,ngx_array_t, ngx_pool_t 等等,对于内存池,nginx设计的十分精炼 ...
- 极高效内存池实现 (cpu-cache)
视频请看 : http://edu.csdn.net/course/detail/627 1.内存池的目的 提高程序的效率 减少运行时间 避免内存碎片 2.原理 要解决上述两个问题,最好的方法就是 ...
随机推荐
- 安装requests
requests包让Python程序能够轻松地向网站请求信息以及检查返回的响应.要安装requests,请执行类似于下面的命令: $ pip3 install --user requests http ...
- 如何在 JavaScript 中检查字符串是否包含子字符串?
如何在 JavaScript 中检查字符串是否包含子字符串? // var test4 = _.includes(string, substring); 该方法需要此文件 <script src ...
- 【Java】数组的打印输出
import java.util.Arrays; public class Test { public static void main(String[] args) { int[] a = { 1, ...
- 【转】VueJS中学习使用Vuex详解
转自:https://segmentfault.com/a/1190000015782272 在SPA单页面组件的开发中 Vue的vuex和React的Redux 都统称为同一状态管理,个人的理解 ...
- java -jar demo.jar
部署springboot项目 生成jar包其实还是依赖springboot的jar才能跑起来,为什么呢? 1.在C盘手工创建了一个文件夹,是拷贝了demo.jar这个jar包运行是报错的. 2.在D: ...
- Django Restframework 实践(二)
按照自己的方法来写接口 ''' @api_view([ 'POST','GET',]) 允许请求的是get或post方法,这里去掉get那么就不能用get方法请求 @permission_classe ...
- python虚拟环境virtualenv下安装MySQL-python
1.先在windows安装:https://github.com/konglingxi/mysqldb_for_python27 2.按照提示将python主环境中的mysqldb相关文件及文件夹移到 ...
- FastReport.Net使用:[33]高亮显示
1.首先来看下初始报表,很简单很普通. 2.下面对报表改进,90分以上的成绩以绿色显示,60~70分的以橙色斜体显示. 报表设计中选择数据成绩文本框,然后点击工具栏上的“ab突出显示”按钮打开“高亮显 ...
- JMS介绍:我对JMS的理解和认识
[ZT]JMS介绍:我对JMS的理解和认识 转自:http://blog.csdn.net/KimmKing/archive/2011/06/30/6577021.aspx,感谢作者KimmKing ...
- [HNOI2012]集合选数 --- 状压DP
[HNOI2012]集合选数 题目描述 <集合论与图论>这门课程有一道作业题,要求同学们求出\({1,2,3,4,5}\)的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x ...