博客新地址:https://github.com/AngryHacker/articles/blob/master/src/code_reading/memorypool.md
什么是内存池?什么是 C++ 的 allocator?
内存池简单说,是为了减少频繁使用 malloc/free new/delete 等系统调用而造成的性能损耗而设计的。当我们的程序需要频繁地申请和释放内存时,频繁地使用内存管理的系统调用可能会造成性能的瓶颈,嗯,是可能,毕竟操作系统的设计也不是盖的(麻麻说把话说太满会被打脸的(⊙v⊙))。内存池的思想是申请较大的一块内存(不够时继续申请),之后把内存管理放在应用层执行,减少系统调用的开销。
那么,allocator 呢?它默默的工作在 C++ 所有容器的内存分配上。默默贴几个链接吧:
http://www.cnblogs.com/wpcockroach/archive/2012/05/10/2493564.html
http://blog.csdn.net/justaipanda/article/details/7790355
http://www.cplusplus.com/reference/memory/allocator/
http://www.cplusplus.com/reference/memory/allocator_traits/
当你对 allocator 有基本的了解之后,再看这个项目应该会有恍然大悟的感觉,因为这个内存池是以一个 allocator 的标准来实现的。一开始不明白项目里很多函数的定义是为了什么,结果初步了解了 allocator 后才知道大部分是标准接口。这样一个 memory pool allocator 可以与大多数 STL 容器兼容,也可以应用于你自定义的类。像作者给出的例子 —— test.cpp, 是用一个基于自己写的 stack 来做 memory pool allocator 和 std::allocator 性能的对比 —— 最后当然是 memory pool allocator 更优。
项目:
Github:MemoryPool
基本使用:
因为这是一个 allocator 类,所以所有使用 std::allocator 的地方都可以使用这个 MemoryPool。在项目的 test.cpp 中,MemoryPool 作为 allocator 用于 StackAlloc(作者实现的 demo 类) 的内存管理类。定义如下:
StackAlloc<int, MemoryPool<int> > stackPool;
其次,你也可以将其直接作为任一类型的内存池,用 newElement 创建新元素,deleteElement 释放元素,就像 new/delete 一样。用下面的例子和 new/delete 做对比:
#include <iostream>
#include <cassert>
#include <time.h>
#include <vector>
#include <stack>
#include "MemoryPool.h"
using namespace std;
/* Adjust these values depending on how much you trust your computer */
#define ELEMS 1000000
#define REPS 50
int main()
{
clock_t start;
MemoryPool<size_t> pool;
start = clock();
for(int i = 0;i < REPS;++i)
{
for(int j = 0;j< ELEMS;++j)
{
// 创建元素
size_t* x = pool.newElement();
// 释放元素
pool.deleteElement(x);
}
}
std::cout << "MemoryPool Time: ";
std::cout << (((double)clock() - start) / CLOCKS_PER_SEC) << "\n\n";
start = clock();
for(int i = 0;i < REPS;+