在這裡 ,還是先介紹下我們這邊對象記憶體池技術的基本概念和設計過程: 所謂的對象記憶體池技術設計過程如下: 首先為某種對象預先生成若幹個空閑對象 ,并且使用對象管理類進行管理。應用程式在需要使用此對象時,即向管理對象申請空閑對象.管理對象即檢視對象記憶體池,如果發現存在未使用空閑對象,即配置設定給申請者。如果發現已無空閑對象,可自行擴充對象記憶體池,并且滿足申請對象的需求,也可以直接傳回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 為了保證多線程安全,我們在對象申請和釋放過程中加入 Lock進行鎖定,保證每次隻有一個線程操作對象池。