文章首次发表在baidu的博客上,专业人士来的太少,所以挪到这里来了
内存池对于长时间运行的程序特别有用,可以减少内存碎片,提高效率,避免内存益 处等众多好处,网上流传的内存池模型有很多种大致分为固定快大小的链表(本文采用的),这种内存池的优点是速度快,碎片少,缺点是灵活性不足,但对于搞定 能的服务器端程序而言很多的数据都是已知的,为了追求速度这种牺牲是可以理解的;另外还有基于大块内存的可变长度内存分配方法,优点是对于字符串类似的应 用提供了很好的解决方法,缺点是要自己管理碎片,相当于在系统的内存管理之上再构建一个内存管理,同样有查找合适内存快的开销;
本文采用的是固定内存快的内存池,当所要求分配的内存大于快的大小时则直接交由系统分配,以后才会采用其他的方式写出内存池,采取性能最优原则,另外对于多线程还需要系统锁,也会增加开销,如何权衡需要多种方案对比才能得出结论。
源代码如下,经测试直接分配达到测试的循环需求需要500毫秒左右,采用内存池在100毫秒左右
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "testStruct.h"
#define BLKSIZ 80 //回收块的大小
#define STKSIZ 4000 //每块内存大小
struct BLOCK
{
char *link;
char data[BLKSIZ];
};
static struct BLOCK * heap;
static struct BLOCK * top_of_heap;
static struct BLOCK * btm_of_heap;
int kint=0;
/*初始化*/
void Init_heap()
{
unsigned blk;
struct BLOCK *ptr;
heap=(struct BLOCK *)malloc(BLKSIZ);//第一个快
btm_of_heap=heap;
ptr=heap;
for(blk=0;blk<500;blk++)
{
ptr->link=(struct BLOCK *)malloc(BLKSIZ);
ptr=ptr->link;
}
ptr->link=NULL;
top_of_heap=ptr;
}
/*根据系统需求增加新的块*/
void expendMem()
{
unsigned blk;
struct BLOCK *ptr;
heap=(struct BLOCK *)malloc(BLKSIZ);//第一个快
top_of_heap=heap;
ptr=heap;
for(blk=0;blk<49;blk++)
{
ptr->link=(struct BLOCK *)malloc(BLKSIZ);
ptr=ptr->link;
}
ptr->link=NULL;
top_of_heap=ptr;
kint++;
printf(" %i ",kint);
}
/*释放一个区域的内存*/
void My_Free(struct BLOCK *ptr)
{
if(ptr>=btm_of_heap)
{
if(ptr<top_of_heap)
{
ptr->link=heap;
heap=ptr;
return;
}
else
{
free(ptr);
//printf("释放");
return;
}
}
puts("/nAttempt to free blocks ");
}
/*申请一块内存*/
void *Allocate(unsigned bytes)
{
void *ptr;
if(bytes<=BLKSIZ)
{
if(heap!=NULL)
{
ptr=heap;
heap=heap->link;
return ptr;
}
else
{
expendMem();
}
}
if(ptr=malloc(bytes))
{
return ptr;
}
puts("//Ins memory");
}
/*主函数*/
int main()
{
int j=0;
int lint=0;
struct BLOCK *p[1000];
char User[20] = {"xiaoming"} ;
// char Password[20] = "123456";
DWORD last,current;
last=GetTickCount();
Init_heap();
for(j=0;j<500;j++)
{
int i;
for(i=0;i<1000;i++)
{
p[i]=Allocate(20);// New(struct Login,1);
strcpy(p[i]->data,User);
// strcpy(p->Password,Password);
}
for(i=0;i<1000;i++)
My_Free(p[i]);
}
heap=btm_of_heap;
while(heap->link!=NULL)
{/*循环输出内存管理链表中的序列号,看看有没有断链*/
lint++;
printf("l:%i ",lint);
heap=heap->link;
}
current=GetTickCount();
printf("总共耗时 %d",current-last);
}