分配固定大小对象的内存池

//下面的代码思想取自efficient c++ 1 //////////////////////////////////////////////////////////////////////////
 2 //可分为:1.内存池本身的创建和删除
 3 //        2.内存池中空闲内存的维护
 4 //两个部分区分开,逻辑就清晰了。
 5 //by wangpei 2015.1.4
 6 /////////////////////////////////////////////////////////////////////////
 7 template <typename T>
 8 class MemoryPool{
 9 public:
10     MemoryPool(size_t size = EXSIZE);
11     ~MemoryPool();
12     inline void* alloca(size_t size);
13     inline void free(void *element);
14 private:
15     enum {EXSIZE = 32};
16     MemoryPool<T> *next;
17     void expand(size_t s = EXSIZE);
18 };
19 template<typename T>
20 MemoryPool<T>::MemoryPool(size_t size)
21 {
22     expand(size);
23 }
24
25 template<typename T>
26 MemoryPool<T>::~MemoryPool()
27 {
28     MemoryPool<T> * ptr;
29     while (next){
30        ptr = next->next;
31        delete[] freeNode; //指针指向了正确的初始位置,就能够正确的释放空间
32        de++;
33        next = ptr;
34     }
35 }
36
37 template<typename T>
38 inline void* MemoryPool<T>::alloca(size_t size)
39 {
40     if (next == 0)
41        expland();
42     MemoryPool<T>* currentFree = next;
43     next = next->next;
44     return currentFree;
45 }
46
47 template<typename T>
48 inline void MemoryPool<T>::free(void *element)
49 {
50     MemoryPool<T>* head = static_cast<MemoryPool<T>* >(doomed); //注意此处的链表维护,不能让链表断开了
51     head->next = next;
52     next = head;
53 }
54
55 template<typename T>
56 void MemoryPool<T>::expand(size_t s)
57 {
58     const size_t s = (sizeof(MemoryPool<T>*) >= sizeof(T)) ? sizeof(MemoryPool<T>*) : sizeof(T);//这里是关键,根据类型的大小确定堆大小
59     MemoryPool<T>* head = (MemoryPool<T>*)new char[s];  //将char*强制转换为MemoryPool<T>* 可读性很差,但却高效的利用了内存空间
60     ma++;
61     head->next = next;
62     freeNode = head;
63     for (size_t i = 0; i < EXPANSION; i++){
64        head = (MemoryPool<T>*)new char[s];
65        ma++;
66        head->next = next;
67        next = head;
68     }
69 }
70 class Rational_tem{
71 private:
72     static MemoryPool<Rational_tem> * memPool;
73     int n;
74     int d;
75 public:
76     Rational_tem(int a = 0, int b = 1) :n(a), d(b){}
77     void* operator new (size_t s)
78     {
79        return memPool->alloca(s);
80     }
81     void operator delete(void* doomed, size_t s)
82     {
83        return memPool->free(doomed);
84     }
85     static void newMemPool()
86     {
87        memPool = new MemoryPool < Rational_tem > ;
88     }
89     static void deleteMemPool()
90     {
91        delete memPool;
92     }
93 };

有个地方需要注意:内存池不保证分配出去的内存都能够回收,所有new的对象,必须delete后,才能够正确的回收。所以,内存池销毁时,是通过从链表头开始向下释放资源。

该内存池应用在Rational_tem这样的类大量new、delete,在短时间重复数量越多,提升的速度越快。

时间: 2024-08-26 21:43:28

分配固定大小对象的内存池的相关文章

efficient c++,单线程内存池

基于 http://www.cnblogs.com/diegodu/p/4555018.html operator new的知识基础上 介绍这个章节的内容 对于一般直接 new 与delete 性能较差,可以自己管理写内存的申请与释放.其实一般的operator new 和operator delete 直接调用 malloc 和 free的. 版本0: class Rational { public: Rational(int a=0, int b =1 ): n(a),d(b){} priv

Python源代码--整数对象(PyIntObject)的内存池

[背景] 原文链接:http://blog.csdn.net/ordeder/article/details/25343633 Python整数对象是不可变对象,什么意思呢?比如运行例如以下python语句 >>>a = 1023 >>>a = 1024 >>>b = a >>>c = 1024 >>>d = 195 >>>e = 195 python的整数对象结构为: typedef struct

Python源码--整数对象(PyIntObject)的内存池

[背景] 原文链接:http://blog.csdn.net/ordeder/article/details/25343633 Python整数对象是不可变对象,什么意思呢?例如执行如下python语句 >>>a = 1023 >>>a = 1024 >>>b = a >>>c = 1024 >>>d = 195 >>>e = 195 python的整数对象结构为: typedef struct {

内存池技术介绍(图文并茂,非常清楚)

看到一篇关于内存池技术的介绍文章,受益匪浅,转贴至此. 原贴地址:http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html 6.1 自定义内存池性能优化的原理 如前所述,读者已经了解到"堆"和"栈"的区别.而在编程实践中,不可避免地要大量用到堆上的内存.例如在程序中维护一个链表的数据结构时,每次新增或者删除一个链表的节点,都需要从内存堆上分配或者释放一定的内存:在维护一个动态数组时,如果动态数组的

内存池技术的原理与实现

6.1 自定义内存池性能优化的原理 如前所述,读者已经了解到"堆"和"栈"的区别.而在编程实践中,不可避免地要大量用到堆上的内存.例如在程序中维护一个链表的数据结构时,每次新增或者删除一个链表的节点,都需要从内存堆上分配或者释放一定的内存:在维护一个动态数组时,如果动态数组的大小不能满足程序需要时,也要在内存堆上分配新的内存空间. 6.1.1 默认内存管理函数的不足 利用默认的内存管理函数new/delete或malloc/free在堆上分配和释放内存会有一些额外的

转 内存池技术的原理与实现

内存池技术的原理与实现 序言 最近在网上看到了几篇篇讲述内存池技术的文章,有一篇是有IBM中国研发中心的人写的,写的不错~~文章地址在本篇blog最后.原文的讲述比我的要清晰很多,我在这只是把我的一些理解和遇到的一些问题和大家分享一下~~ 一.为什么要使用内存池技术呢 主要有两个原因:1.减少new.delete次数,减少运行时间:2.避免内存碎片. 1.效率 c语言中使用malloc/free来分配内存,c++中使用new/delete来分配内存,他们的内存申请与释放都是与操作系统进行交互的.

c++内存池实现

利用C/C++开发大型应用程序中,内存的管理与分配是一个需要认真考虑的部分.本文描述了内存池设计原理并给出内存池的实现代码,代码支持Windows和Linux,多线程安全.内存池设计过程中需要考虑好内存的分配与释放问题,其实也就是空间和时间的矛盾.有的内存池设计得很巧妙,内存分配与需求相当,但是会浪费过多的时间去查找分配与释放,这就得不偿失:实际使用中,我们更多的是关心内存分配的速度,而不是内存的使用效率.基于此,本文按照如下思想设计实现内存池.主要包含三个结构:StiaticMemory, M

C++实现内存池

多进程编程多用在并发服务器的编写上,当收到一个请求时,服务器新建一个进程处理请求,同时继续监听.为了提高响应速度,服务器采用进程池的方法,在初始化阶段创建一个进程池,池中有许多预创建的进程,当请求到达时,只需从池中分配出来一个进程即可:当进程不够用时,进程池将再次创建一批进程.类似的方法可以用在内存分配上. C++中,创建一个复杂的对象需要几十条指令,包括函数调用的代价(寄存器值得保存和恢复),以及构造或复制构造函数体的执行代价,甚至动态分配内存的代价.尤其是,在不重载new和delete运算符

简单的内存池实现gko_alloc

在用gpreftools优化gko_pool的时候我发现一个问题,malloc竟然成了性能瓶颈 由于在每个连接建立的时候gko_pool默认会为读写各分配2KB的buf备用,这个是比较固定的 每个连接的的生命周期会伴随着4KB大小的内存malloc & free 正好可以写个只能分配固定大小内存的"内存池",基本思路就是每次分配一个大内存bucket(64MB),需要4KB的块的时候就从bucket中取,当bucket没有可用slot就再分配一个新的bucket,当bucket