所谓的对象内存池技术设计过程如下:
首先为某种对象预先生成若干个空闲对象
,并且使用对象管理类进行管理。应用程序在需要使用此对象时,即向管理对象申请空闲对象.管理对象即检视对象内存池,如果发现存在未使用空闲对象,即分配给申请者。如果发现已无空闲对象,可自行扩充对象内存池,并且满足申请对象的需求,也可以直接返回NULL,表明对象申请失败。在程序获取对象并且使用后,想释放此对象资源时。继续想管理对象提出申请释放对象,管理对象接受到释放对象后将其再次放入对象池,成为可使用对象。
看了上面的介绍后,接下来以伪代码的方式来更加清晰的展现对象获取和释放的过程。
申请对象
OBJ*
ApplyObj(void)
{
if 存在空闲对象
{
OBJ *pIdleObj = NULL;
pIdleObj = GetIdleObj(); //获取空闲对象
return pIdleObj;
}
//不存在空闲对象,处理方式如下
方式1:
ExtendObjectPool(); //扩充对象池
OBJ *pIdleObj = NULL;
pIdleObj = GetIdleObj(); //获取空闲对象
return pIdleObj;
方法2:
return NULL;
}
释放对象
void
ReleaseObj(OBJ* pObj)
{
if(pObj!=NULL)
{
AddToObjectPool(pObj); //对象再次加入到对象池
}
}
有了上面的这些说明,我想大家对于对象内存池技术应该都有了一个大概了解吧!
(其实没有什么高深的技术,只是一些简单的应用,大家用一个平常心来看待就可以了!)接下介绍具体来实现这个对象内存池,我们需要做些什么?
在实现对象内存池之前,先提出几个我们需要达到的目标:
u
对象内存池管理对象具有广泛的通用性,也就是说能够满足应用程序生成各个不同的对象池,例如:P
layer对象池、Monster对象池、NPC对象池。
u
产生对象的速度一定要快于直接使用
new/delete或者malloc/free方式很多倍。
u
对象池容量具有可扩展性和纠错能力。也就是说在无空闲对象时,管理对象类能够自动生成一批新的空闲对象供上层使用,同时能够正确指出目前所使用对象是否为合法对象池对象。
u
对象的申请和释放,必须具备多线程安全性。也就是说在服务器程序通过各个不同线程同时访问对象池管理时,能够保证合法获取和释放池对象。
基于上面这些问题条件,这里先提供几种简单易行的解决方案来供大家参考。其他解决方案还有很多,我也就不一一列举了!靠大家独立思考和发挥了。:
)
解决方案1:(单链表实现)
u
第一步,分配模板对象数组,并且用指针保存。
u
第二步,建立一单链表管理类,将已经分配成功的数组对象,分配到
单链表中,同时设置表头和表尾指针。
u
第三步,从对象池中申请对象,首先检测链表中是否存在可使用空闲对象。如果没有可返回
NULL,也可以先锁定扩充链表(保存扩展对象数组指针)。然后返回可使用对象给用户。
u
第四步,释放对象池对象时,首先将表尾指针指向被释放对象,接下来被回收对象为此链表表尾。完成释放过程。
u
最后,内存释放,
delete数组指针。
图例演示如下:
解决方案2:(双链表实现)
u
为了能够使我们建立的对象池能够在应用程序中通用,我们考虑使用模板
template<class OBJ>来生成我们的class CObjectPool.
u
为了能够快速获取对象,我们采用双向链表的方式来建立我们的对象池。对象获取从当前链表头开始进行,对象释放直接加到链表尾。操作过程中需要使用一附加指针对象表明当前可使用对象位置。若此指针为
NULL,表明已无可使用空闲对象。
u
为了生成一个一定容量的对象池,我们可以通过模板的方式也可以通过初始化
Init方式来生成初始对象池。在申请过程中无空闲对象,需要向系统重新一定数目对象,并且按照顺序加到链表尾。实现对象池的可扩充性。
u
为了保证多线程安全,我们在对象