用模版实现简单的内存池
程序中有时候会遇到这种情况,就是需要不停的去分配以及释放内存。带来的是不停的调用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
用模版实现简单的内存池相关推荐
- 实现自己的operator new和operator delete以及实现一个简单的内存池管理类
为什么有必要写自己的operator new和operator delete? 为了效率.缺省的operator new和operator delete具有非常好的通用性,它的这种灵活性也使得在某些特 ...
- (转载)简单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 ...
- C++ 析构函数与内存池
2019独角兽企业重金招聘Python工程师标准>>> C++ Primer 书中也提到编写 class 时要注意 copy control 成员(拷贝构造函数,赋值操作符,析构函数 ...
- boost pool内存池库使用简要介绍
2019独角兽企业重金招聘Python工程师标准>>> 我厂内存次神马的一般都自己实现.我曾经也自己写过一个demo(mempool).后来发现boost库里面有一个内存池库boos ...
- 内存池的设计和实现总结(一)
C/C++下内存管理是让几乎每一个程序员头疼的问题,分配足够的内存.追踪内存的分配.在不需要的时候释放内存--这个任务相当复杂.而直接使用系统调用malloc/free.new/delete进行内存分 ...
- 一个轻量级内存池的实现与细节
引言 内存池作为一种的内存管理机制被广泛地运用于各种领域当中,内存池拥有快速的内存分配与更加健壮的管理机制,同时在不同的平台与环境当中也拥有不同的实现方式,本文提出一种轻量级的内存池实现,可以非常方便 ...
- Nginx 内存池似懂非懂?一文带你看清高性能服务器内存池
nginx 内存池 ngx_pool_t nginx 是自己实现了内存池的,所以在nginx ngx_pool_t 这个结构也随处可见,这里主要分析一下内存池的分配逻辑. 内存池实现了包括小块内存.大 ...
- [项目设计]高并发内存池
目录 1.项目介绍 2.高并发内存池整体框架设计 3.thread cache <1>thread cache 哈希桶对齐规则 <2>Thread Cache类设计 4.Cen ...
- “池化技术”漫谈 - 线程池,内存池,连接池……
池化技术 - 简单点来说,就是提前保存大量的资源,以备不时之需,O(∩_∩)O,对于线程,内存,oracle的连接对象等等,这些都是资源,程序中当你创建一个线程或者在堆上申请一块内存时,都涉及到很多系 ...
最新文章
- 《CLR Via C# 第3版》笔记之(十四) - 泛型高级
- Java使用MyEclipse2017时的一些小细节
- C++ Primer 5th笔记(3)字符串、向量和数组:字符串
- springboot activiti工作流简单示例
- MySQL文件后_MySQL误删除文件后,如何恢复
- BBIAF的完整形式是什么?
- 云原生落地困挑战无处不在?我选Serverless
- java springboot b2b2c shop 多用户商城系统源码(四):熔断器Hystrix
- golang map转json的顺序问题
- Foobar2000的配置及优化
- Android拨号盘,支持T9搜索和号码搜索
- 【软件测试】使用C++ Test进行动态测试
- LDPC — 信道编码
- springboot基于web的摩托车销售系统的设计与实现毕业设计源码031706
- 五种典型开发周期模型(瀑布、V、原型化、螺旋、迭代)
- paddle.paramattr转换为torch框架下算法
- JAVA正则表达式,matcher.find()和 matcher.matches()的区别
- python怎么改成白底_教你用OpenCV 和 Python给证件照换底色(蓝底 -红底-白底)...
- Linux_Linux_sort 命令
- codeforces contest 985E. Pencils and Boxes+思维
热门文章
- java解析excel的js页面,Java导入Excel文件页面实现JS
- Mooc的Python3学习笔记
- 《C++ Primer 第五版》(第4.1-4.11节) ——运算符的执行顺序问题,负值坐商取余问题,数值的移位操作
- Epoll详解及源码分析
- 【C++11新特性】 C++11智能指针之unique_ptr
- 条件变量实现线程同步
- Gdb 调试core文件详解
- 7年老Android一次操蛋的面试经历,深度好文
- 小企业服务器设置位置,小企业服务器配置
- 合并两个链表,去掉重复元素