基于 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++,单线程内存池的更多相关文章

  1. 内存池-转载自IBM

    [转载自IBM]讲的很好~推荐看看 6.1 自定义内存池性能优化的原理 如前所述,读者已经了解到"堆"和"栈"的区别.而在编程实践中,不可避免地要大量用到堆上的 ...

  2. C++实现简单的内存池

    多进程编程多用在并发服务器的编写上,当收到一个请求时,服务器新建一个进程处理请求,同时继续监听.为了提高响应速度,服务器采用进程池的方法,在初始化阶段创建一个进程池,池中有许多预创建的进程,当请求到达 ...

  3. golang 内存池

    一般来说,内存池都是采用预分配的方式,分为固定大小的和非固定大小块,固定大小的内存效率高,非固定大小灵活.同时,分为单线程和多线程版的,单线程不需要考虑并发问题. 一般内存池的实现思想:分配一块比较大 ...

  4. 内存分配(new/delete,malloc/free,allocator,内存池)

    以下来源http://www.cnblogs.com/JCSU/articles/1051826.html 程序员们经常编写内存管理程序,往往提心吊胆.如果不想触雷,唯一的解决办法就是发现所有潜伏的地 ...

  5. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  6. berkeley db 内存池分配机制

    __memp_alloc() 注: MPOOL_ALLOC_SEARCH_DYN 没有 出现在 bdb document上, 也没出现在 除了mp_alloc外的代码里. 先删了 以便代码清楚. 按 ...

  7. NGINX 内存池有感

    写在前面 写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑. 也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究. 整个NGINX系列 ...

  8. 【uTenux实验】内存池管理(固定内存池和可变内存池)

    1.固定内存池管理实验 内存管理是操作系统的一个基础功能.uTenux的内存池管理函数提供了基于软件的内存池管理和内存块分配管理.uTenux的内存池有固定大小的内存池和大小可变的内存池之分,它们被看 ...

  9. boost的线程池和内存池 智能指针

    内存池为boost自带的 #include <boost/pool/pool.hpp> 或者另外一个开源的库: nedmalloc 一个高效率的库 线程池需要下载另外一个开源库 http: ...

随机推荐

  1. 【程序员的SQL金典】笔记(第6章~第11章)

        第六章 索引与约束   1.索引用来提高数据的检索速度,而约束则用来保证数据的完整性.   2.创建索引 创建索引的SQL 语句是CREATE INDEX,其语法如下: CREATE INDE ...

  2. AIDL实现Android IPC

    1.AIDL文本解释 在软件工程中,接口定义语言(IDL)已经成为通用术语,是用来描述软件组件接口的特定语言.在Android中,该IDL被称为Android接口定义语言(AIDL),它是纯文本文件, ...

  3. 检测SqlServer服务器内存是否瓶颈

    性能监视器临视以下数据: Memory->Available MBytes  可用的内存  windows系统不低于1G,如果可用内存不多,则系统要求sqlserver释放内存 Paging F ...

  4. 【Android学习】尺寸单位 px in mm pt dp sp

    一.Android中支持的尺寸单位 下面用表格的方式将Android中支持的尺寸单位列举,供大家参考: Android的尺寸单位  单位表示  单位名称  单位说明  px  像素  屏幕上的真实像素 ...

  5. C# IO操作(五)文件的递归加载

    本篇是一个案例,其核心通过代码展示代码中的递归这个用法,程序的界面如下:

  6. asp.net 文件上传示例整理

    ASP.NET依托.net framework类库,封装了大量的功能,使得上传文件非常简单,主要有以下三种基本方法. 方法一:用Web控件FileUpload,上传到网站根目录.  代码如下 复制代码 ...

  7. CodeSmith Template Model Output

    背景:上学那会儿就接触CodeSmith,是一款非常优秀的代码自动生成工具.以前写过好些基本模版,可惜早不知道扔到哪儿去了,如今只能重新开始,把它捡回来,加油. 效果:将数据库 DataBase 应用 ...

  8. (转)Facebook内部分享:26个高效工作的小技巧

    春节假期马上就要结束了,该收收心进入新一年的工作节奏了~分享 26 个高效工作的小技巧,希望对大家有所帮助~(我发现自己只有最后一条执行得很好,并且堪称完美!) 1.时间常有,时间优先. 2.时间总会 ...

  9. SOCKET编程:为什么recv不阻塞

    服务器端: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #incl ...

  10. Java中的栈:java.util.Stack类

    public class Stack<E>extends Vector<E>Stack 类表示后进先出(LIFO)的对象堆栈.它通过五个操作对类 Vector 进行了扩展 ,允 ...