内存池
0. 什么是内存池
内存池的逻辑非常简单,就是池化技术的一种,所有池的核心思想就在于创建某个物体和销毁的开销有点大,但是又需要频繁的创建和销毁。我们就预先创建一个池子,里面预先创建了大量的这个物体。你要的时候就给你一个,你不要的时候就还回去。无论是线程池,内存池,对象池,连接池实际上都是这么一个道理。
但实际上一般的malloc和new都是对一些小的空间预先做了内存池的(即频繁的new 1个字节的开销可能比你想象中的要小)。有兴趣的可以去看看侯捷老师的《C++内存》,其中对内存池讲解了很多。
我们这里写的一个内存池思想源自loki库中一个内存池实现。算是比较简单且实用的一个版本吧。
1. 模板特化
一般情况下,我们使用内存池都是为了针对某个特定大小的对象。所以模板的使用非常方便。
template <int ITEM_SIZE>
class MemPool
: noncopyable
{
public:
void Clear(); // 清空内存池所有内存
void *Alloc();
void Free(void *);
private:
}
2. 结构
首先,既然要实现内存池,那么我们就需要一个很大块的内存。
enum{
ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE)};
union Item{
Item *next;
char itemData[ITEM_SIZE];
};
struct Block{
Item items[ITEMS_PER_BLOCK];
};
2.1 内嵌指针
既然这里是在做内存池,分配多余的内存给指针变量是非常浪费内存的。所以我们用了内嵌指针的做法。
union的要点其实就是三点。
- 其大小取决于最大的成员的大小。
- 其在一个时刻只能表现出一个成员的属性。
- 我认为使用union还有一个很大的好处就是就是