經典的記憶體池(mempool)技術,是一種用于配置設定大量大小相同的小對象的技術。通過該技術可以極大加快記憶體配置設定/釋放過程。
記憶體池隻涉及兩個靜态常量:Block_Size(mempool的容量大小)、Item_Size(小對象的大小,但不能小于指針的大小,在32位平台也就是不能小于4位元組),以及兩個指針變量BlockNodeHead、FreeItemNodeHead。開始,這兩個指針均為空。
其中指針變量BlockNodeHead是把所有申請的記憶體塊(Block_Node)串成一個連結清單,以便通過它可以釋放所有申請的記憶體。FreeItemNodeHead變量則是把所有自由記憶體結點(Item_Node)串成一個鍊。
詳細資訊請檢視http://www.itgrass.com/a/cjj/C-jc/200706/29-9836.html
下面給出完整執行個體代碼:
#ifndef _MEMPOOL_H
#define _MEMPOOL_H
class Mempool
{
public:
Mempool();
~Mempool();
void* Alloc();
void Free(void* p);
private:
const static int Block_Size = 1024;
const static int Item_Size = 16;
struct Item_Node
{
struct Item_Node *next;
char data[Item_Size - sizeof(Item_Node*)];
};
struct Block_Node
{
struct Block_Node *next;
Item_Node data[Block_Size / Item_Size];
};
Block_Node* BlockNodeHead;
Item_Node* freeItemNodeHead;
};
#endif
#include <iostream>
#include "mempool.h"
using namespace std;
Mempool::Mempool():BlockNodeHead(NULL),freeItemNodeHead(NULL)
{
}
Mempool::~Mempool()
{
Block_Node* tmp = BlockNodeHead;
while(tmp != NULL)
{
BlockNodeHead = BlockNodeHead->next;
delete tmp;
tmp = BlockNodeHead;
}
}
void* Mempool::Alloc()
{
if(freeItemNodeHead == NULL)
{
Block_Node* tmpBlockNode = new Block_Node;
if(tmpBlockNode == NULL)
{
perror("No memory!/n");
exit(1);
}
if(BlockNodeHead == NULL)
{
BlockNodeHead = tmpBlockNode;
BlockNodeHead->next = NULL;
}
else
{
tmpBlockNode->next = BlockNodeHead;
BlockNodeHead = tmpBlockNode;
}
freeItemNodeHead = &(tmpBlockNode->data[0]);
int i = 0;
while(i < Block_Size/Item_Size - 1)
{
tmpBlockNode->data[i].next = &(tmpBlockNode->data[i + 1]);
++i;
}
tmpBlockNode->data[i].next = NULL;
}
Item_Node* allocItemNode = freeItemNodeHead;
freeItemNodeHead = freeItemNodeHead->next;
return allocItemNode;
}
void Mempool::Free(void* p)
{
Item_Node* tmpItemNode = static_cast<Item_Node*>(p);
tmpItemNode->next = freeItemNodeHead;
freeItemNodeHead = tmpItemNode;
}
int main()
{
Mempool pool;
char* p = NULL;
int i = 0;
while(i < 100000)
{
p = static_cast<char*>(pool.Alloc());
strcpy(p, "Hello");
cout<<i<<" : "<<p<<endl;
++i;
pool.Free(p);
}
return 0;
}