java 内存池_基于一个简单定长内存池的实现方法详解

本文详细介绍了如何实现一个简单的基于C++的定长内存池,包括结构体block的设计、内存池的构造与析构、内存分配与释放的方法。内存池在Java中用于提高内存管理效率,通过预分配内存并重复使用,减少了频繁的内存申请和释放操作。
摘要由CSDN通过智能技术生成

#include

#include

#include

#include

using namespace std;

struct block {

block * next;

unsigned int numofChunks;//指向下一个block指针

unsigned int numofFreeChunks;//剩余free的chunk数量

unsigned int blockNum;//该block的编号

char * data;

//记录可用chunk序号

queue freepos;

block(unsigned int _numofChunks ,unsigned int _chunkSize, unsigned int _blockNum){

numofChunks =  _numofChunks;

numofFreeChunks = _numofChunks;

blockNum = _blockNum;

next = NULL;

data = new char [numofChunks * (sizeof(unsigned int) + sizeof(void *) + _chunkSize)];

char * p = data;

//每个chunk的结构:4byte的chunk序号 + 4byte的所属block地址 + 真正的数据

for(int i=0;i

char * ptr = p + i * (_chunkSize +  sizeof(unsigned int) + sizeof(void *));

unsigned int * num = (unsigned int *)(ptr);

*num = i;

ptr += sizeof(void *);

int * blockpos = (int *) ptr;

*blockpos = (int)this;

freepos.push(i);

}

}

~block(){

delete [] data;

}

};

class memoryPool {

public :

memoryPool(unsigned int _chunkSize = 256, unsigned int _initNumofChunks = 4096, unsigned int _steps = 64){

initNumofChunks = _initNumofChunks;

chunkSize = _chunkSize;

steps = _steps;

numofBlocks = steps;

//创建内存池时,初始化一定数量的内存空间

block * p = new block(initNumofChunks, chunkSize, 0);

blocksPtr = p;

for(int i=1;i

p->next = new block(initNumofChunks, chunkSize, i);

p = p->next;

blocksPtrTail = p;

}

firstHasFreeChunksBlock = blocksPtr;

}

~memoryPool(){

block  * p = blocksPtr;

while(blocksPtr!=NULL){

p = blocksPtr->next;

delete blocksPtr;

blocksPtr = p;

}

}

/*

从firstHasFreeChunksBlock开始查找第一个有free位置的block,

如果找到,则则获取该block的freepos的对首元素,

返回该元素序号对应的chunk的数据地址,并将freepos的队首元素弹出,

其他相关属性更新。如果找不到,则新增steps个chunk,再重复上面的过程。

*/

void * allocate(){

block * p = firstHasFreeChunksBlock;

while(p != NULL && p->numofFreeChunks <= 0) p = p->next;

if(p == NULL){

p = blocksPtrTail;

increaseBlocks();

p = p->next;

firstHasFreeChunksBlock = p;

}

unsigned int pos =  p->freepos.front();

void * chunkStart = (void *)(p->data + pos * (chunkSize +  sizeof(unsigned int) + sizeof(void *)));

void * res = chunkStart + sizeof(unsigned int) + sizeof(void *);

p->freepos.pop();

p->numofFreeChunks --;

return res;

}

void increaseBlocks(){

block * p = blocksPtrTail;

for(int i=0; i

p->next = new block(initNumofChunks, chunkSize, numofBlocks);

numofBlocks++;

p = p->next;

blocksPtrTail = p;

}

}

/*

传入待释放的地址指针_data,

通过对_data的地址移动可以找到chunk中的ChunkNum和blockAddress两个数据,

通过blockAddress可以找到该chunk所属的block,

然后将ChunkNum添加到该block的freepos中,其他相应属性更新。

*/

void freeMemory(void * _data){

void * p = _data;

p -= sizeof(void *);

int * blockpos = (int *) p;

block * b = (block *) (*blockpos);

p -= sizeof(unsigned int);

int * num = (int *) p;

b->freepos.push(*num);

b->numofFreeChunks ++;

if (b->numofFreeChunks > 0 && b->blockNum < firstHasFreeChunksBlock->blockNum)

firstHasFreeChunksBlock = b;

}

private :

unsigned int initNumofChunks; //每个block的chunk数量

unsigned int chunkSize;//每个chunk的数据大小

unsigned int steps;//每次扩展的chunk数量

unsigned int numofBlocks;//当前管理多少个blocks

block * blocksPtr;//指向起始block

block * blocksPtrTail;//指向末尾block

block * firstHasFreeChunksBlock;//指向第一个不为空的block

};

//test

void echoPositionNum(char * p){

p -= (sizeof(void *) + sizeof(unsigned int));

int * num = (int *) p;

cout<

}

//测试

void test0(){

memoryPool mp;

char * s1 = (char *)mp.allocate();

char * s2 = (char *)mp.allocate();

char str [256];

char str2 [256];

char str3 [256];

for(int i=0; i<255; i++) {

str[i] = 'a';str2[i] = 'b';str3[i] = 'c';

}

str[255] = '\0';

str2[255] = '\0';

strcpy(s1,str);

strcpy(s2,str2);

str3[255] = '\0';

echoPositionNum(s1);

cout<

mp.freeMemory(s1);

echoPositionNum(s2);

cout<

char * s3 = (char *)mp.allocate();

strcpy(s3,str3);

echoPositionNum(s3);

cout<

}

void test1(){

clock_t clock_begin = clock();

const int N = 50000;

char * s[N];

int round = 100;

while(round>=0){

round --;

for(int i=0;i

s[i] = new char[256];

}

for(int i=0;i

delete [] s[i];

}

}

clock_t clock_end = clock();

cout<

}

void test2(){

memoryPool mp(256);

clock_t clock_begin = clock();

const int N = 50000;

char * s[N];

int round = 100;

while(round>=0){

round --;

for(int i=0;i

s[i] = (char *)mp.allocate();

}

for(int i=0;i

mp.freeMemory(s[i]);

}

}

clock_t clock_end = clock();

cout<

}

int main()

{

test0();

test1();

test2();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值