程序中有时候会遇到这种情况,就是需要不停的去分配以及释放内存。带来的是不停的调用new以及delete带来的开销。

而且由于全局的new以及delete往往对多线程做出了并发保护,所以在单线程情况下这更带来一种浪费,一般的情况下是去实现一个

单线程的内存池来进行性能优化,配合所需的类往往带来很好的性能提升。

首先是作为内存池的模板类:

 1 template<class T>
 2 class MemoryPool{
 3 public:
 4     MemoryPool(size_t size = EXPANSION_SIZE);
 5     ~MemoryPool();
 6
 7     //从空闲列表中分配T大小的空间
 8     inline void * alloc(size_t size);
 9
10     //释放内存到空闲列表中
11     inline void free(void * elements);
12 private:
13     MemoryPool<T> * next;   //空闲列表的下一个元素
14     enum { EXPANSION_SIZE = 32 };
15     void expandTheFreeList(int howMany = EXPANSION_SIZE);
16 };
17
18 template<class T>
19 MemoryPool<T>::MemoryPool(size_t size)
20 {
21     expandTheFreeList(size);
22 }
23
24 template<class T>
25 MemoryPool<T>::~MemoryPool()
26 {
27     MemoryPool<T> * nextPtr = next;
28     if (next){
29         for (nextPtr = next; nextPtr != nullptr; nextPtr = next){
30             next = next->next;
31             delete[] ((char * )nextPtr);    //这里的强制类型转换应该注意,不转换编译无法通过的当时分配
32                                             //内存的时候是按照char类型分配的,那么释放的时候也应该同样释放。
33         }
34     }
35 }
36
37
38 template<class T>
39 inline
40 void * MemoryPool<T>::alloc(size_t)
41 {
42     if (!next)
43         expandTheFreeList();
44     MemoryPool<T> * head = next;
45     next = head->next;//分配了一块空间
46     return head;
47 }
48
49 template<class T>
50 inline
51 void MemoryPool<T>::free(void * doomed)
52 {
53     MemoryPool<T> * head = static_cast<MemoryPool<T> *>(doomed);
54     head->next = next;
55     next = head;
56 }
57
58 template<class T>
59 void MemoryPool<T>::expandTheFreeList(int howMany)
60 {
61     //保证分配的内存大小至少应该是大于指针大小或者是元素大小中的 最大者,因为二者之间是共享内存的
62     size_t sizeAlloc = (sizeof(T) > sizeof(MemoryPool<T> *)) ?
63         sizeof(T) : sizeof(MemoryPool<T> *);
64     MemoryPool<T> * runner = (MemoryPool<T>*)(new char[sizeAlloc]); //这里实际上是可以使用static_cast的,但是不知道为什么,
65     next = runner;                                              //gcc下编译不能通过。可能因为gcc的限制比较严格。无奈,只能使用普通的强制类型转换
66     for (int i = 0; i < howMany; ++i){
67         runner->next = (MemoryPool<T>*)(new char[sizeAlloc]);
68         runner = runner->next;
69     }
70     runner->next = 0;
71 }

下面是使用该内存池的一个rational类,代码如下:

 1 class Rational{
 2 public:
 3     Rational(int a = 0, int b = 1):n(a), d(b){}
 4     void * operator new(size_t size){return memPool->alloc(size); }
 5     void operator delete(void * doomed, size_t size){memPool->free(doomed);}
 6     static void newMemPool(){memPool = new MemoryPool<Rational>; }
 7     static void deleteMemPool()
 8     {
 9         if(!memPool)
10             return;
11         delete memPool;
12     }
13 private:
14     int n;
15     int d;
16     static MemoryPool <Rational> * memPool;
17 };

使用代码如下:

 1 MemoryPool<Rational> * Rational::memPool = 0;
 2
 3 int main()
 4 {
 5     Rational * array[10];
 6     Rational::newMemPool();
 7     for(int j = 0; j < 2; ++j){
 8         for(int i = 0; i < 10; i++){
 9             array[i] = new Rational(i);
10         }
11         for(int i = 0; i < 10; i++){
12             delete array[i];
13         }
14     }
15     Rational::deleteMemPool();
16 }

转载于:https://www.cnblogs.com/-wang-cheng/p/4950452.html

用模版实现简单的内存池相关推荐

  1. 实现自己的operator new和operator delete以及实现一个简单的内存池管理类

    为什么有必要写自己的operator new和operator delete? 为了效率.缺省的operator new和operator delete具有非常好的通用性,它的这种灵活性也使得在某些特 ...

  2. (转载)简单linux C++内存池

    C++代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ...

  3. C++ 析构函数与内存池

    2019独角兽企业重金招聘Python工程师标准>>> C++ Primer 书中也提到编写 class 时要注意 copy control 成员(拷贝构造函数,赋值操作符,析构函数 ...

  4. boost pool内存池库使用简要介绍

    2019独角兽企业重金招聘Python工程师标准>>> 我厂内存次神马的一般都自己实现.我曾经也自己写过一个demo(mempool).后来发现boost库里面有一个内存池库boos ...

  5. 内存池的设计和实现总结(一)

    C/C++下内存管理是让几乎每一个程序员头疼的问题,分配足够的内存.追踪内存的分配.在不需要的时候释放内存--这个任务相当复杂.而直接使用系统调用malloc/free.new/delete进行内存分 ...

  6. 一个轻量级内存池的实现与细节

    引言 内存池作为一种的内存管理机制被广泛地运用于各种领域当中,内存池拥有快速的内存分配与更加健壮的管理机制,同时在不同的平台与环境当中也拥有不同的实现方式,本文提出一种轻量级的内存池实现,可以非常方便 ...

  7. Nginx 内存池似懂非懂?一文带你看清高性能服务器内存池

    nginx 内存池 ngx_pool_t nginx 是自己实现了内存池的,所以在nginx ngx_pool_t 这个结构也随处可见,这里主要分析一下内存池的分配逻辑. 内存池实现了包括小块内存.大 ...

  8. [项目设计]高并发内存池

    目录 1.项目介绍 2.高并发内存池整体框架设计 3.thread cache <1>thread cache 哈希桶对齐规则 <2>Thread Cache类设计 4.Cen ...

  9. “池化技术”漫谈 - 线程池,内存池,连接池……

    池化技术 - 简单点来说,就是提前保存大量的资源,以备不时之需,O(∩_∩)O,对于线程,内存,oracle的连接对象等等,这些都是资源,程序中当你创建一个线程或者在堆上申请一块内存时,都涉及到很多系 ...

最新文章

  1. 《CLR Via C# 第3版》笔记之(十四) - 泛型高级
  2. Java使用MyEclipse2017时的一些小细节
  3. C++ Primer 5th笔记(3)字符串、向量和数组:字符串
  4. springboot activiti工作流简单示例
  5. MySQL文件后_MySQL误删除文件后,如何恢复
  6. BBIAF的完整形式是什么?
  7. 云原生落地困挑战无处不在?我选Serverless
  8. java springboot b2b2c shop 多用户商城系统源码(四):熔断器Hystrix
  9. golang map转json的顺序问题
  10. Foobar2000的配置及优化
  11. Android拨号盘,支持T9搜索和号码搜索
  12. 【软件测试】使用C++ Test进行动态测试
  13. LDPC — 信道编码
  14. springboot基于web的摩托车销售系统的设计与实现毕业设计源码031706
  15. 五种典型开发周期模型(瀑布、V、原型化、螺旋、迭代)
  16. paddle.paramattr转换为torch框架下算法
  17. JAVA正则表达式,matcher.find()和 matcher.matches()的区别
  18. python怎么改成白底_教你用OpenCV 和 Python给证件照换底色(蓝底 -红底-白底)...
  19. Linux_Linux_sort 命令
  20. codeforces contest 985E. Pencils and Boxes+思维

热门文章

  1. java解析excel的js页面,Java导入Excel文件页面实现JS
  2. Mooc的Python3学习笔记
  3. 《C++ Primer 第五版》(第4.1-4.11节) ——运算符的执行顺序问题,负值坐商取余问题,数值的移位操作
  4. Epoll详解及源码分析
  5. 【C++11新特性】 C++11智能指针之unique_ptr
  6. 条件变量实现线程同步
  7. Gdb 调试core文件详解
  8. 7年老Android一次操蛋的面试经历,深度好文
  9. 小企业服务器设置位置,小企业服务器配置
  10. 合并两个链表,去掉重复元素