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=, int b = ): n(a),d(b){}
private:
int n;
int d;
};
版本1:专用的内存管理器
#include <stddef.h> // for size_t
#include <iostream> using namespace std; class NextOnFreeList {
public:
NextOnFreeList *next;
}; class Rational {
public:
Rational (int a = , int b = ) : n(a), d(b) {}
inline void *operator new(size_t size);
inline void operator delete(void *doomed, size_t size); static void newMemPool() { expandTheFreeList(); }
static void deleteMemPool(); private:
static NextOnFreeList *freeList; // A free list of Rational objects.
static void expandTheFreeList();
enum { EXPANSION_SIZE = }; int n; // Numerator
int d; // Denominator
}; inline
void * Rational::operator new(size_t size)
{
if ( == freeList) {// If the list is empty, fill it up.
expandTheFreeList();
} NextOnFreeList *head = freeList;
freeList = head->next; return head;
} inline
void Rational::operator delete(void *doomed, size_t size)
{
NextOnFreeList *head = static_cast <NextOnFreeList *> (doomed);
head->next = freeList;
freeList = head;
} void Rational::expandTheFreeList()
{
// We must allocate an object large enough to contain the next
// pointer.
size_t size = (sizeof(Rational) > sizeof(NextOnFreeList *)) ?
sizeof(Rational) : sizeof(NextOnFreeList *); // NextOnFreeList *runner = static_cast <NextOnFreeList *>(new char[size]);
NextOnFreeList *runner = (NextOnFreeList *)(new char[size]); freeList = runner;
for (int i = ; i < EXPANSION_SIZE; i++) {
//runner->next = static_cast <NextOnFreeList *> (new char[size]);
runner->next = (NextOnFreeList *)(new char[size]);
runner = runner->next;
} runner->next = ; cout << "expand" << endl;
} void Rational::deleteMemPool()
{
NextOnFreeList *nextPtr;
for (nextPtr = freeList; nextPtr != NULL; nextPtr = freeList) {
freeList = freeList->next;
delete [] nextPtr;
}
}
//测试code NextOnFreeList *Rational::freeList = ; int main()
{
Rational *array[]; Rational::newMemPool(); // Start timing here for (int j = ; j < ; j++) {
for (int i = ; i < ; i++) {
array[i] = new Rational(i);
}
for (int i = ; i < ; i++) {
delete array[i];
}
} // Stop timing here Rational::deleteMemPool(); return ;
}
这版本是通过重载 目标类 中的new 与delete 实现内存管理,只适用于目标类,但是速度是最快的。
实现方式是维护一个链表,类中静态声明链表头,链表维护一串空间,通过类型转换在 目标类 和 链表指针 之间转换。
如果内存不够(freelist=NULL)是一次申请较多内存进行维护。
链表的添加删除(对于函数释放空间与申请空间)是在链首操作。
书上47 行 52行通过 静态类型转换不成功,改为了 强制转换,在 g++ 中能够编译运行。
主要在主函数中调用静态函数 链表的申请与释放。
版本2:固定大小对象的内存池
考虑版本1,可以通过模板实现管理特定的对象。最主要的参数是类的大小。
实现是专门声明一个管理内存的内存池类,使用模板实现,提供alloc() free() 接口,给类申请与释放内存。
内存池类的实现是自身有一个MemoryPool<T>* next 指针用来指向维护的链表,内存的操作都在链首位置。
#include <stddef.h>
#include <iostream> using namespace std; template <class T>
class MemoryPool {
public:
MemoryPool (size_t size = EXPANSION_SIZE);
~MemoryPool (); // Allocate a T element from the free list.
inline void* alloc (size_t size); // Return a T element to the free list.
inline void free (void *someElement);
private:
// next element on the free list.
MemoryPool<T> *next; // If the freeList is empty, expand it by this amount.
enum { EXPANSION_SIZE = }; // Add free elements to the free list
void expandTheFreeList(int howMany = EXPANSION_SIZE);
}; template <class T>
MemoryPool <T> :: MemoryPool (size_t size)
{
expandTheFreeList(size);
} template < class T >
MemoryPool < T > :: ~MemoryPool ()
{
MemoryPool<T> *nextPtr = next;
for (nextPtr = next; nextPtr != NULL; nextPtr = next) {
next = next->next;
cout << nextPtr << endl;
//delete [] nextPtr;
//delete nextPtr;
delete [](char*)nextPtr; //不太明白为什么这样是对的,上面的方法不行。。
//明白了,因为new的时候就是用char字节的方法申请的,delete的时候要对应。。
}
} template < class T >
inline
void* MemoryPool < T > :: alloc (size_t)
{
if (!next) {
expandTheFreeList();
} MemoryPool<T> *head = next;
next = head->next; return head;
} template < class T >
inline
void MemoryPool < T > :: free (void *doomed)
{
MemoryPool<T> *head = static_cast <MemoryPool<T> *> (doomed); head->next = next;
next = head;
} template < class T >
void MemoryPool < T > :: expandTheFreeList(int howMany)
{
// We must allocate an object large enough to contain the
// next pointer.
size_t size = (sizeof(T) > sizeof(MemoryPool<T> *)) ?
sizeof(T) : sizeof(MemoryPool<T> *); //MemoryPool<T> *runner = static_cast <MemoryPool<T> *>(new char [size]);
MemoryPool<T> *runner = (MemoryPool<T> *)(new char [size]); next = runner;
for (int i = ; i < howMany ; i++) {
//runner->next = static_cast <MemoryPool<T> *> new char [size];
runner->next = (MemoryPool<T> *)( new char [size]);
runner = runner->next;
}
runner->next = NULL;
} class Rational {
public:
Rational (int a = , int b = ) : n(a), d(b) {} void *operator new(size_t size) { return memPool->alloc(size); }
void operator delete(void *doomed,size_t size)
{ memPool->free(doomed); } static void newMemPool() { memPool = new MemoryPool <Rational>; }
static void deleteMemPool() { delete memPool; }
private:
int n; // Numerator
int d; // Denominator static MemoryPool <Rational> *memPool;
}; MemoryPool <Rational> *Rational::memPool = ; int main()
{
Rational *array[]; Rational::newMemPool(); // Start timing here for (int j = ; j < ; j++) {
for (int i = ; i < ; i++) {
array[i] = new Rational(i);
}
for (int i = ; i < ; i++) {
delete array[i];
}
} // Stop timing here Rational::deleteMemPool(); }
efficient c++,单线程内存池的更多相关文章
- 内存池-转载自IBM
[转载自IBM]讲的很好~推荐看看 6.1 自定义内存池性能优化的原理 如前所述,读者已经了解到"堆"和"栈"的区别.而在编程实践中,不可避免地要大量用到堆上的 ...
- C++实现简单的内存池
多进程编程多用在并发服务器的编写上,当收到一个请求时,服务器新建一个进程处理请求,同时继续监听.为了提高响应速度,服务器采用进程池的方法,在初始化阶段创建一个进程池,池中有许多预创建的进程,当请求到达 ...
- golang 内存池
一般来说,内存池都是采用预分配的方式,分为固定大小的和非固定大小块,固定大小的内存效率高,非固定大小灵活.同时,分为单线程和多线程版的,单线程不需要考虑并发问题. 一般内存池的实现思想:分配一块比较大 ...
- 内存分配(new/delete,malloc/free,allocator,内存池)
以下来源http://www.cnblogs.com/JCSU/articles/1051826.html 程序员们经常编写内存管理程序,往往提心吊胆.如果不想触雷,唯一的解决办法就是发现所有潜伏的地 ...
- 基于C/S架构的3D对战网络游戏C++框架_05搭建系统开发环境与Boost智能指针、内存池初步了解
本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...
- berkeley db 内存池分配机制
__memp_alloc() 注: MPOOL_ALLOC_SEARCH_DYN 没有 出现在 bdb document上, 也没出现在 除了mp_alloc外的代码里. 先删了 以便代码清楚. 按 ...
- NGINX 内存池有感
写在前面 写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑. 也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究. 整个NGINX系列 ...
- 【uTenux实验】内存池管理(固定内存池和可变内存池)
1.固定内存池管理实验 内存管理是操作系统的一个基础功能.uTenux的内存池管理函数提供了基于软件的内存池管理和内存块分配管理.uTenux的内存池有固定大小的内存池和大小可变的内存池之分,它们被看 ...
- boost的线程池和内存池 智能指针
内存池为boost自带的 #include <boost/pool/pool.hpp> 或者另外一个开源的库: nedmalloc 一个高效率的库 线程池需要下载另外一个开源库 http: ...
随机推荐
- django 学习-7 模型数据操作
1.首先还是创建办一个项目和一个应用 django.admin.py startproject ssj cd ssj django.admin.py startapp sdj 那 ...
- centos6.5下磁盘分区及挂载
1..查看磁盘空间 2.磁盘分区 3.格式化分区 4.挂载/卸载
- Web前端设计:Html强制不换行<nobr>标签用法代码示例
在网页排版布局中比如文章列表标题排版,无论多少文字均不希望换行显示,需要强制在一行显示完内容.这就可以nobr标签来实现.它起到的作用与word-break:keep-all 是一样的.nobr 是 ...
- C# 微信扫码支付 回调页面
.NET版 微信扫码支付,官方推荐使用[模式二] 一.微信扫码支付模式一: 1.回调页面:官方demo中example文件下的NativeNotifyPage.aspx 2.微信回调地址:http:/ ...
- Git 的简单使用
一直在使用Git,仅限于简单的使用,但还是记不住几个简单.在这边总结一下,加深印象,也方便查找. 安装Git 平常主要在windows和ubuntu上工作,就以windows为例,Linux和Mac平 ...
- 上下问语句句柄Release地方
OCI--在QUERY中 CLI--在FETCH中 在父类中定义了public—Release和protected—Release,protected—Release在public—Release中被 ...
- python(三)一个文件读写操作的小程序
我们要实现一个文件读写操作的小程序 首先我们有一个文件 我们要以"============"为界限,每一个角色分割成一个独立的txt文件,按照分割线走的话是分成 xiaoNa_1. ...
- android 获取手机号
android 获取手机号码,由于运营商的管理方式的不同,所以获取手机号码的方式也可能完全相同.现在很多运营商并不会把手机号码存入sim卡中. 最简单的,比如说中国移动并不将手机号保存在sim卡中,只 ...
- PHP学习之环境搭建
计算机环境 win7 64位 搭建 apache-httpd-2.2-win64 + php-5.3.6-Win32-VC9-x64 +MySQL_5.5.13_winx64开发环境 参考: ...
- linux内核中sys_poll()的简化分析
app:poll or select; kernel: sys_poll(); do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,st ...