读书人

小议内存储器池、资源池

发布时间: 2012-07-30 16:19:05 作者: rapoo

小议内存池、资源池

比较简单的一篇文章。本来是有些地方没想明白,想分析一下。结果写着写着就明白了,才发现如此简单。留之~

?

简单的定义

我对一些专业的名词不怎么熟悉,没有很系统的学习过,所以先稍微解释下我的一点概念上的认识:

看见过很多类似的词,比如 高速缓存分配、内存对象池、对象池、连接池等等。

我觉得一个池已经带有高速的意义了,所以很少加上高速的称呼;

而内存对象池和对象池,对象的意义太广,包括了资源和内存,更适用一种后缀符的修饰。而资源更倾向一个抽象层的分配性,内存是一种本质上的空间申请。可以称线程对象池,连接对象池,而直接称对象池有点不明所指;

资源池是一个抽象的概念,比如线程池,连接池,文件IO池等等。更倾向一种高层资源符号的占用。比如一个文件IO,你用一个指针保存即可,不涉及到对内存的太敏感性。

也就是说,在我的认识里,分配分两种,一种是空间上的,一种是高层资源符号的占用,在对他们的称呼上可能大家不是很赞同,但没关系,只是在文章头起到一个定义作用,以免下文的混淆。


(注意:以下都是讨论行为特点,不对效率上的写法讨论。效率的东西可以考虑我的上文“缓存的力量”)

?

?

内存池的行为特点

比如以下一个简单的对象:

?

class CPlay{public:   void CPlay()   {       //清零各个对象   }private:    char name[24];    int age;    char buffer1[100];};class CKmem{void *GetMem();void *FreeMem(void *p);};T t;void *p = CKmem.GetMem();CPlay *pPlay = new (p)CPlay;//...pPlap->~CPlay();CKmem.FreeMem(pPlay);

?

假设这是一个游戏人物中的对象数据,在每回申请的时候,必须调用构造函数来进行初始化。因为它占有的资源符号就是内存,并没有什么可继承性的东西。

?

资源池的行为特点

我们按照内存池的思维方式来一遍,文件IO的:

?

class CFile{public:CFile();{p = fopen(.....);}~CFile(){close(p);}int Write(const char *pBuffer, int size);FILE *p;};T t;void *p = CKmem.GetMem();CFile *pFile = new (p)CFile;//...pFile->~CFile();CKmem.FreeMem(pFile);

?

?好像没什么问题。等等,当你第二次再次GetMem()的时候,发生了什么? p又被重新创建了一次。于是FILE *p就一直往返于创建和删除之间。这符合池的原则吗?池的原则就是重复的快速利用,减少申请的开销。也就是说根本不考虑是怎么释放的。加上一个释放,不是多次一举吗?所以不能用对象池的思想来编写资源池。资源池的特点是,对抽象资源符号的占有,瓶颈在申请的过程上。所以它本身(符号)对内存的要求几乎没有,比如一个event,只是个int型在记录。在保存上,你想用对象池的方法来写也行。就比如linux下的slub,是利用内存片头4个字节来记录地址。如果你熟悉这种技巧,就可以申请一个8字节的大小来存放。这个slub也已经由我仿写成windows下的版本

读书人网 >操作系统

热点推荐