專利名稱:一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法及系統(tǒng)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及對(duì)象管理技術(shù),尤其涉及一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法及系統(tǒng)。
背景技術(shù):
隨著網(wǎng)絡(luò)游戲應(yīng)用越來(lái)越廣泛,用于管理游戲數(shù)據(jù)的游戲服務(wù)器逐漸要承載數(shù)以千計(jì)甚至更多的用戶游戲數(shù)據(jù)。以一個(gè)采用面向?qū)ο蟪绦蛟O(shè)計(jì)的游戲服務(wù)進(jìn)程為例,一個(gè)游戲服務(wù)進(jìn)程需要支持最大3000個(gè)在線游戲用戶、2000個(gè)游戲房間、以及2000個(gè)游戲邏輯對(duì)象等。由于游戲服務(wù)器需要長(zhǎng)時(shí)間、連續(xù)地提供游戲服務(wù),因此,當(dāng)游戲服務(wù)進(jìn)程因?yàn)楹?jiǎn)單邏輯改動(dòng)、或運(yùn)行出錯(cuò)(Crash)時(shí),游戲服務(wù)進(jìn)程的內(nèi)存數(shù)據(jù)會(huì)全部丟失,此時(shí)就需要重啟進(jìn)程,才能繼續(xù)提供服務(wù)。 目前,在較短時(shí)間間隔內(nèi)游戲服務(wù)進(jìn)程再次啟動(dòng)時(shí),有兩種恢復(fù)內(nèi)存數(shù)據(jù)的方法一種是,需要所有游戲用戶離線并重新登錄,通過(guò)數(shù)據(jù)庫(kù)(DB)或數(shù)據(jù)文件(File)重建游戲用戶對(duì)象,并繼續(xù)提供游戲服務(wù)。但是,這種方式由于所有游戲用戶均會(huì)被踢下線并需要重新登錄,且游戲服務(wù)進(jìn)程會(huì)停機(jī)或Crash時(shí)刻的所有游戲內(nèi)容上下文會(huì)丟失,因此會(huì)嚴(yán)重影響用戶的使用體驗(yàn)。另一種是,通過(guò)操作系統(tǒng)內(nèi)核提供的共享內(nèi)存機(jī)制,游戲用戶不需要離線并重新登錄,而直接恢復(fù)游戲用戶的游戲數(shù)據(jù)和對(duì)象,并繼續(xù)游戲服務(wù)。這種方式能應(yīng)對(duì)游戲服務(wù)程序?qū)Ω呖捎?、高可靠的要求以? (天)*24 (小時(shí))的運(yùn)營(yíng)需求,因此,業(yè)界普遍采用共享內(nèi)存的方式支持游戲數(shù)據(jù)的迅速恢復(fù)。但是,如何基于共享內(nèi)存實(shí)現(xiàn)對(duì)象的管理與自動(dòng)恢復(fù),目前還沒(méi)有完整、安全和高效的解決方案。
發(fā)明內(nèi)容
有鑒于此,本發(fā)明的主要目的在于提供一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法及系統(tǒng),能夠?qū)崿F(xiàn)共享內(nèi)存上對(duì)象的高效管理與自動(dòng)恢復(fù)。為達(dá)到上述目的,本發(fā)明的技術(shù)方案是這樣實(shí)現(xiàn)的本發(fā)明提供了一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法,包括注冊(cè)托管到MTO系統(tǒng)的類型和類型組,并建立類型與類型組之間的關(guān)聯(lián)關(guān)系;根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池;由內(nèi)存池完成托管類型的管理與恢復(fù)。上述方案中,所述建立類型組與其對(duì)應(yīng)的共享內(nèi)存區(qū)域的映射關(guān)系包括al、計(jì)算支持所有托管到MTO系統(tǒng)的類型和類型組所需要的共享內(nèi)存總大小(TotalSize);a2、根據(jù)當(dāng)前應(yīng)用進(jìn)程傳入的共享內(nèi)存關(guān)鍵值ShmKey和計(jì)算的TotalSize大小,創(chuàng)建或重新獲得共享內(nèi)存對(duì)象,并調(diào)用shmatO將獲得的共享內(nèi)存段連接到應(yīng)用進(jìn)程;a3、在共享內(nèi)存首部創(chuàng)建CSharedMem對(duì)象,并記錄共享內(nèi)存元數(shù)據(jù);a4、遍歷每個(gè)類型組,逐一為每個(gè)類型組在共享內(nèi)存區(qū)域映射固定大小內(nèi)存池,保存映射關(guān)系并完成內(nèi)存池上對(duì)象的初始化或恢復(fù)。上述方案中,所述對(duì)共享內(nèi)存的管理為通過(guò)對(duì)象創(chuàng)建接口完成的對(duì)象創(chuàng)建;所述對(duì)象創(chuàng)建包括查找類型組映射的內(nèi)存池的頭部CObjMng ;從空閑列表FreeList找到空閑索引塊CIdx[i],根據(jù)類型Type在對(duì)應(yīng)空閑數(shù)據(jù)塊CObj [i]的首地址執(zhí)行placement new創(chuàng)建對(duì)象,對(duì)應(yīng)的索引塊CIdx[i]從FreeList刪除,并加入使用列表UsedList中。上述方案中,所述對(duì)共享內(nèi)存的管理為通過(guò)對(duì)象獲取接口完成的 對(duì)象獲??;所述對(duì)象獲取包括查找類型組映射的內(nèi)存池的頭部CObjMng ;根據(jù)請(qǐng)求下標(biāo)i直接查找對(duì)應(yīng)索引塊CIdx[i];檢查CIdx[i]使用狀態(tài)并返回對(duì)應(yīng)的數(shù)據(jù)塊CObj [i]。上述方案中,所述對(duì)共享內(nèi)存的管理為通過(guò)對(duì)象釋放接口完成的對(duì)象釋放;所述對(duì)象釋放包括查找類型組映射的內(nèi)存池的頭部CObjMng ;根據(jù)請(qǐng)求下標(biāo)i直接查找對(duì)應(yīng)索引塊CIdx[i];檢查CIdx[i]使用狀態(tài),并將CIdx[i]從UsedList刪除,重新加入FreeList0該方法進(jìn)一步包括引入MTO系統(tǒng)抽象基類CObj,所有托管到MTO系統(tǒng)的類型均必須直接或間接派生自cobj,支持單繼承或多繼承方式。上述方案中,為每個(gè)注冊(cè)類型組分配的共享內(nèi)存區(qū)域包括管理頭、索引域和數(shù)據(jù)域。本發(fā)明還提供了一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)系統(tǒng),包括ΜΤ0托管類型/類型組注冊(cè)模塊、MTO接口層、以及MTO共享內(nèi)存管理模塊;其中,所述MTO托管類型/類型組注冊(cè)模塊,用于記錄所有托管到MTO系統(tǒng)的類型和類型組的元數(shù)據(jù)信息,并建立類型和類型組之間的關(guān)聯(lián)關(guān)系;所述MTO接口層,用于建立類型和類型組與其對(duì)應(yīng)的共享內(nèi)存區(qū)域的映射關(guān)系;所述MTO共享內(nèi)存管理模塊,用于對(duì)MTO接口層確定的、對(duì)應(yīng)各個(gè)類型組的共享內(nèi)存區(qū)域進(jìn)行管理。上述方案中,所述MTO共享內(nèi)存管理模塊包括共享內(nèi)存自身元數(shù)據(jù)記錄部分、以及固定大小內(nèi)存池管理部分;相應(yīng)的,所述共享內(nèi)存包括共享內(nèi)存元數(shù)據(jù)空間和內(nèi)存池空間。本發(fā)明所提供的基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法及系統(tǒng),注冊(cè)托管到MTO系統(tǒng)的類型和類型組,并建立類型與類型組之間的關(guān)聯(lián)關(guān)系;根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池;由內(nèi)存池完成托管類型的管理與恢復(fù)。如此,能對(duì)托管到MTO系統(tǒng)的類型的對(duì)象實(shí)現(xiàn)包括分配、獲取和釋放在內(nèi)的統(tǒng)一管理、以及恢復(fù)。由于在具體實(shí)現(xiàn)過(guò)程中,對(duì)基于共享內(nèi)存的對(duì)象創(chuàng)建、訪問(wèn)和釋放這些操作均由接口層提供的操作接口代理,因此,上層應(yīng)用在實(shí)現(xiàn)時(shí)只需調(diào)用相應(yīng)的接口,無(wú)需關(guān)心底層的實(shí)現(xiàn)細(xì)節(jié),如開發(fā)人員不需要關(guān)心對(duì)象的管理和恢復(fù)操作細(xì)節(jié),操作簡(jiǎn)單、方便、易于實(shí)現(xiàn),而且安全、高效。由于托管到MTO系統(tǒng)的各個(gè)類型組在特定的共享內(nèi)存區(qū)域都映射內(nèi)存池,那么,當(dāng)游戲服務(wù)器因?yàn)楹?jiǎn)單邏輯升級(jí)或Bug修復(fù)等需要停機(jī)維護(hù)、甚至在進(jìn)程出錯(cuò)退出且共享內(nèi)存數(shù)據(jù)完整的情況下,共享內(nèi)存的特性可繼續(xù)保持游戲數(shù)據(jù),待到維護(hù)完成后游戲服務(wù)進(jìn)程重新啟動(dòng)后,再由MTO系統(tǒng)自動(dòng)找回相應(yīng)對(duì)象的上下文游戲數(shù)據(jù),并繼續(xù)提供游戲服務(wù),進(jìn)而實(shí)現(xiàn)了對(duì)數(shù)據(jù)快速、高效地恢復(fù),保證了數(shù)據(jù)的連續(xù)性、完整性、以及可靠性,能為用戶提供更好、更滿意的游戲服務(wù)。
圖I為本發(fā)明基于共享內(nèi)存的對(duì)象管理與恢復(fù)系統(tǒng)的組成結(jié)構(gòu)示意圖;圖2為CSharedMem類結(jié)構(gòu)不意圖;圖3為類型組到內(nèi)存池空間的映射示意圖;
圖4為CObjMng/CIdx/CObj固定大小內(nèi)存池類結(jié)構(gòu)示意圖;圖5為共孕內(nèi)存區(qū)域?yàn)榭臻e時(shí)的布局不意圖;圖6為共享內(nèi)存區(qū)域首部創(chuàng)建CSharedMem對(duì)象后的布局示意圖;圖7為按類型組劃分CObjMng/CIdx/CObj固定大小內(nèi)存池后共享內(nèi)存區(qū)域的布局示意圖;圖8為本發(fā)明基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法的實(shí)現(xiàn)流程示意圖;圖9為MTO托管類型/類型組注冊(cè)模塊類結(jié)構(gòu)示意圖;圖10為類型的繼承體系示意圖;圖11為內(nèi)存池的初始狀態(tài)示意圖;圖12為創(chuàng)建對(duì)象后內(nèi)存池狀態(tài)示意圖;圖13為對(duì)象釋放后內(nèi)存池狀態(tài)示意圖。
具體實(shí)施例方式針對(duì)Linux系統(tǒng)共享內(nèi)存的特性,對(duì)于基于共享內(nèi)存的對(duì)象管理與恢復(fù)需要考慮三個(gè)方面的問(wèn)題第一、共享內(nèi)存的創(chuàng)建與重新獲取。操作系統(tǒng)支持共享內(nèi)存機(jī)制,內(nèi)核以(ShmKey,Size)標(biāo)識(shí)共享內(nèi)存段,通過(guò)將該共享內(nèi)存段連接到進(jìn)程的地址空間中,能保證該地址空間內(nèi)的數(shù)據(jù)可以在進(jìn)程停止后得以保持;進(jìn)程重啟后將以相同的(ShmKey,Size)標(biāo)識(shí)重新找回共享內(nèi)存段,并再次將該共享內(nèi)存段連接到進(jìn)程的地址空間,如此,就可重新取回原先共享內(nèi)存段上保存的數(shù)據(jù)。由于操作系統(tǒng)并不能保證相同的共享內(nèi)存段,兩次連接到進(jìn)程地址空間時(shí)具有相同的首地址,因此,記錄這兩次首地址差值為偏移量offset。第二,對(duì)象指針數(shù)據(jù)成員的恢復(fù)。共享內(nèi)存保持?jǐn)?shù)據(jù)的特性,使得普通數(shù)據(jù)內(nèi)容方便恢復(fù);但指針數(shù)據(jù)恢復(fù)時(shí),需要偏移量offset修正后才能正確使用。第三,對(duì)象虛表指針的恢復(fù)。因?yàn)檫壿婤ug的修正會(huì)導(dǎo)致程序重新編譯后再重啟,此時(shí)類型的虛表地址可能會(huì)發(fā)生變化,這樣恢復(fù)后的對(duì)象虛表指針就無(wú)效了 ;所以需要在原對(duì)象地址空間,重新執(zhí)行定位new(placement new),將對(duì)象的虛表指針指向正確的虛表地址?;谏鲜隹紤],本發(fā)明的基本思想是注冊(cè)托管到MTO系統(tǒng)的類型和類型組,并建立類型與類型組之間的關(guān)聯(lián)關(guān)系;根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池;由內(nèi)存池完成托管類型的管理與恢復(fù)。其中,所述類型組信息包括但不限于類型列表、類型組容納元素最大數(shù)量、類型組元素最大空間;并且,可根據(jù)所有類型組信息計(jì)算得出一塊連續(xù)的共享內(nèi)存區(qū)域總大小。本發(fā)明提供的基于共享內(nèi)存的對(duì)象管理與恢復(fù)系統(tǒng)如圖I所示,該系統(tǒng)也可稱為多類型對(duì)象(MTO,Multi-Type Object)系統(tǒng),該系統(tǒng)包括ΜΤ0托管類型/類型組注冊(cè)模塊
11、MT0接口層12、以及MTO共享內(nèi)存管理模塊13 ;其中,所述MTO托管類型/類型組注冊(cè)模塊11,可簡(jiǎn)稱為MTORegister,用于記錄所有托管到MTO系統(tǒng)的類型(TypeUnit)和類型組(GroupUnit)的元數(shù)據(jù)信息,并建立類型和類型組之間的關(guān)聯(lián)關(guān)系。這里,托管到MTO系統(tǒng)的類型可以根據(jù)功能需求和邏輯約束關(guān)系,劃分為一個(gè) 或多個(gè)類型組,比如設(shè)置用戶組、房間組、游戲邏輯組等。每個(gè)類型僅且只能注冊(cè)到一個(gè)類型組,每個(gè)類型組中至少包含一個(gè)類型。類型組記錄類型列表、類型組容納元素最大數(shù)量、類型組元素最大空間等元數(shù)據(jù),比如類型組A包括類型Al、類型A2,容納數(shù)量為CountA,每個(gè)元素空間為Max(sizeof (Al), sizeof (A2));類型組B包括類型BI、類型B2、類型B3、類型B4,容納數(shù)量為CountB,每個(gè)元素空間為Max (sizeof (BI),sizeof (B2),sizeof (B3), sizeof (B4));類型組C包括類型Cl,容納數(shù)量為CountC,每個(gè)元素空間為Max (sizeof (Cl))等。本發(fā)明中,引入MTO系統(tǒng)抽象基類CObj,所有托管到MTO系統(tǒng)的類型均必須直接或間接派生自CObj、支持單繼承或多繼承方式。如此,MTO系統(tǒng)才可對(duì)托管的類型納入到自身的管理體系中,實(shí)現(xiàn)統(tǒng)一的管理與恢復(fù)操作。所述MTO接口層12,可簡(jiǎn)稱為MTOAllocator,處于整個(gè)MTO系統(tǒng)總控的位置,用于建立類型和類型組與其對(duì)應(yīng)的共享內(nèi)存區(qū)域的映射關(guān)系;具體的,控制完成共享內(nèi)存大小計(jì)算、共享內(nèi)存的創(chuàng)建或找回、劃分共享內(nèi)存區(qū)域并初始化或恢復(fù)共享內(nèi)存上的對(duì)象數(shù)據(jù);具體的,所述MTO接口層12,用于根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池,對(duì)內(nèi)存池使用的對(duì)象完成初始化/恢復(fù)工作。所述MTO共享內(nèi)存管理模塊13,用于對(duì)MTO接口層12確定的、對(duì)應(yīng)各個(gè)類型組的共享內(nèi)存區(qū)域進(jìn)行管理。由于本發(fā)明中MTO系統(tǒng)是以類型組為單位,在共享內(nèi)存區(qū)域?yàn)槊總€(gè)類型組映射內(nèi)存池來(lái)管理和恢復(fù)托管到MTO系統(tǒng)的各個(gè)類型對(duì)象。因此,需要先計(jì)算出所有類型組總共需要占用的內(nèi)存大小,再加上輔助相關(guān)共享內(nèi)存管理數(shù)據(jù)占用大小,即可得出所需使用的共享內(nèi)存區(qū)域的總大小(TotalSize)。所述共享內(nèi)存區(qū)域以(ShmKey,TotalSize)標(biāo)識(shí),其中,ShmKey為共享內(nèi)存關(guān)鍵(key)值;在共享內(nèi)存區(qū)域的首部記錄共享內(nèi)存元數(shù)據(jù),后部以MTORegister中的注冊(cè)類型組為單位,為每個(gè)類型組映射對(duì)應(yīng)的內(nèi)存池。所述MTO共享內(nèi)存管理模塊13的作用就是對(duì)以(ShmKey,TotalSize)標(biāo)識(shí)的共享內(nèi)存區(qū)域進(jìn)行管理;具體的,所述MTO共享內(nèi)存管理模塊13包括兩部分共享內(nèi)存自身元數(shù)據(jù)記錄(CSharedMem)部分、以及固定大小內(nèi)存池(CObjMng/CIdx/CObj)管理部分。相應(yīng)的,所述共享內(nèi)存包括共享內(nèi)存元數(shù)據(jù)空間和內(nèi)存池空間。對(duì)于共享內(nèi)存元數(shù)據(jù)空間,本發(fā)明系統(tǒng)使用CSharedMem對(duì)象記錄共享內(nèi)存自身的元數(shù)據(jù),具體信息包括ShmKey、TotalSize、共享內(nèi)存首地址pAddr、共享內(nèi)存偏移(Offset)、以及共享內(nèi)存使用模式(Mode),如圖2所示。其中,Mode值可以是首次初始化模式(SHM_INIT),SHM_INIT模式表示首次創(chuàng)建共享內(nèi)存段,也可以是重新shmatO后的恢復(fù)模式(SHM_RECOVER), SHM_RECOVER模式表示找回已經(jīng)存在的共享內(nèi)存段;共享內(nèi)存元數(shù)據(jù)空間大小為sizeof (CSharedMem)。這里,shmatO為將共享內(nèi)存連接到進(jìn)程地址空間的函數(shù),簡(jiǎn)稱為連接共享內(nèi)存函數(shù),用于連接內(nèi)核的共享內(nèi)存段到進(jìn)程的地址空間。對(duì)于內(nèi)存池空間,本發(fā)明MTO系統(tǒng)是以類型組為單位,為每個(gè)類型組在共享內(nèi)存上映射一塊內(nèi)存池區(qū)域;該內(nèi)存池空間包含三個(gè)部分管理頭(Sizeof(CObjMng))、索引域(sizeof (CIdx) *Count)和數(shù)據(jù)域(MaxTypeSize*Count),如圖3所示,其中,索引數(shù)組元素?cái)?shù)量Count個(gè),數(shù)據(jù)數(shù)組元素?cái)?shù)量Count個(gè),因此,每個(gè)類型組對(duì)應(yīng)的內(nèi)存池空間大小為sizeof (CObjMng) +sizeof (CIdx) *Count+MaxTypeSize*Count,遍歷所有的類型組即可計(jì)算出內(nèi)存池占用空間的總大小。
圖3為類型組到內(nèi)存池空間的映射示意圖,圖4為CObjMng/CIdx/CObj固定大小內(nèi)存池類結(jié)構(gòu)示意圖,圖3中點(diǎn)填充的部分表示內(nèi)存池管理結(jié)構(gòu),白色填充的區(qū)域表示有效數(shù)據(jù)塊空間。下面結(jié)合圖3和圖4詳細(xì)介紹CObjMng/CIdx/CObj固定大小內(nèi)存池結(jié)構(gòu)。如圖3、圖4所示,在CObjMng/CIdx/CObj固定大小內(nèi)存池結(jié)構(gòu)中,每個(gè)固定大小內(nèi)存池均由管理頭(CObjMng)、索引域(CIdx數(shù)組)、數(shù)據(jù)域(CObj數(shù)組)三部分組成;索引域和數(shù)據(jù)域均按照數(shù)組方式組織,如此,可按數(shù)組下標(biāo)方式進(jìn)行索引,并且,CIdx數(shù)組與CObj數(shù)組按照數(shù)組下標(biāo)存在——對(duì)應(yīng)關(guān)系,如CIdx
描述CObj [O] ;C0bjMng/CIdx采用數(shù)組實(shí)現(xiàn)的雙向鏈表方式將索引域組織成使用鏈表(UsedList)和空閑鏈表(FreeList);CObjMng是MTORegister的類型組在內(nèi)存池上的對(duì)應(yīng),CIdx是MTORegister托管到MTO系統(tǒng)的類型在內(nèi)存池上的對(duì)應(yīng);初始時(shí),所有數(shù)據(jù)塊均是空閑的,所有CIdx均加入FreeList,而UsedList為空值;恢復(fù)時(shí),遍歷UsedList中每個(gè)CIdx對(duì)象,根據(jù)CIdx記錄的Type類型,在CIdx對(duì)應(yīng)的數(shù)據(jù)塊區(qū)域重新placement new,完成數(shù)據(jù)區(qū)對(duì)象的恢復(fù)。本發(fā)明中,共享內(nèi)存區(qū)域的布局如圖5、圖6所示,圖5為以(ShmKey,TotalSize)標(biāo)識(shí)的共享內(nèi)存區(qū)域?yàn)榭臻e時(shí)的布局,其中,pAddr表示該共享內(nèi)存區(qū)域首地址。圖6為在共享內(nèi)存區(qū)域首部創(chuàng)建CSharedMem對(duì)象后的布局,MTO共享內(nèi)存管理模塊13從首地址pAddr開始,使用sizeof (CSharedMem)大小,創(chuàng)建并初始化CSharedMem對(duì)象,記錄共享內(nèi)存元數(shù)據(jù)信息,其中,點(diǎn)填充的部分為CSharedMem部分。根據(jù)MTORegister模塊記錄的每個(gè)類型組信息,在類型組分配的共享內(nèi)存區(qū)域?yàn)槊總€(gè)類型組映射內(nèi)存池CObjMng/CIdx/CObj,圖7以GroupA、GroupB和GroupC舉例,示出了按類型組劃分CObjMng/CIdx/CObj固定大小內(nèi)存池后共享內(nèi)存區(qū)域的布局,圖7中點(diǎn)填充的部分為共享內(nèi)存元數(shù)據(jù)(CSharedMem)和內(nèi)存池管理區(qū)(CObjMng/CIdx),而白色部分是承載有效數(shù)據(jù)對(duì)象部分?;谏厦嫠龅腃ObjMng/CIdx/CObj結(jié)構(gòu),CObjMng/CIdx/CObj支持對(duì)象訪問(wèn)的原理是對(duì)象創(chuàng)建時(shí),從FreeList找到空閑索引塊CIdx[i],其中下標(biāo)為i,根據(jù)類型(Type)在對(duì)應(yīng)空閑數(shù)據(jù)塊CObj [i]的首地址執(zhí)行placement new創(chuàng)建對(duì)象,對(duì)應(yīng)的CIdx [i]從FreeList刪除,并加入到UsedList中。對(duì)象獲取時(shí),根據(jù)請(qǐng)求下標(biāo)i直接查找對(duì)應(yīng)索引塊CIdx[i],檢驗(yàn)CIdx[i]使用狀態(tài)并返回對(duì)應(yīng)的數(shù)據(jù)塊CObj [i]。對(duì)象釋放時(shí),根據(jù)請(qǐng)求下標(biāo)i直接查找對(duì)應(yīng)索引塊CIdx [i],檢驗(yàn)CIdx [i]使用狀態(tài),并將CIdx [i]從UsedList刪除,重新加入到FreeList?;谏鲜鱿到y(tǒng),本發(fā)明所提出的基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法如圖8所示,包括以下步驟步驟810 :注冊(cè)托管到MTO系統(tǒng)的類型和類型組,并建立類型與類型組之間的關(guān)聯(lián)關(guān)系;這里,所述注冊(cè)所有托管到MTO系統(tǒng)的類型和類型組為記錄所有托管到MTO系統(tǒng)的類型和類型組的元數(shù)據(jù)信息。 本步驟中,所述注冊(cè)所有托管到MTO系統(tǒng)的類型和類型組結(jié)合圖9所示,具體包括以下步驟步驟I :調(diào)用 MTORegister 中的 RegisterType (Type, Size)接口,注冊(cè)托管到 MTO系統(tǒng)的類型Type ;其中,MTORegister為每個(gè)托管到MTO系統(tǒng)的類型Type分配TypeUnit結(jié)構(gòu),記錄托管到MTO系統(tǒng)的類型元數(shù)據(jù),TypeUnit記錄的元數(shù)據(jù)信息包括類型名(Type)、類型大小(Size);反復(fù)調(diào)用RegisterType (Type, Size)接口可以注冊(cè)所有托管到MTO系統(tǒng)的類型,如類型Al、類型A2、類型BI、類型B2、類型B3、類型B4、類型Cl。步驟2 :調(diào)用 MTORegister 中的 RegisterGroup (Group, Count)接口,注冊(cè)類型組Group ;其中,MTORegister為每個(gè)類型組分配GroupUnit結(jié)構(gòu),記錄類型組元數(shù)據(jù),GroupUnit記錄的元數(shù)據(jù)信息包括類型組名(Group)、元素?cái)?shù)量(Count)、類型集合(TypeUnitSet),并根據(jù)類型集合自動(dòng)計(jì)算元素大小(MaxTypeSize);反復(fù)調(diào)用RegisterGroup (Group, Count)接口可以注冊(cè)所有類型組,如(GroupA,CountA)、(GroupB, CountB)、(GroupC, CountC)。步驟3 :調(diào)用 MTORegister 中的 BindTypeToGroup (Group,Type)接口,建立類型組Group對(duì)托管到MTO系統(tǒng)的類型Type的包含關(guān)系;其中,BindTypeToGroup(Group, Type)接口根據(jù)組名 Group 查找到對(duì)應(yīng)的GroupUnit記錄項(xiàng),根據(jù)類型名Type查找對(duì)應(yīng)的TypeUnit記錄項(xiàng);將TypeUnit引用到GroupUnit的類型集合中(TypeSet),并根據(jù)TypeUnit的大小(Size)值更新GroupUnit中MaxTypeSize域的值,使其總是記錄組中所有類型的最大Size數(shù)值;反復(fù)調(diào)用BindTypeToGroup (Group, Type)接口可以完成所有類型組與托管到MTO系統(tǒng)的類型之間包含關(guān)系的建立,如(GroupA, Al)、(GroupA, A2)、(GroupB, BI)、(GroupB,B2)、(GroupB, B3)、(GroupB, B4)、(GroupC, Cl)。步驟820 :根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;這里,具體是根據(jù)所有注冊(cè)類型組信息,按照計(jì)算所得的共享內(nèi)存空間總大小(TotalSize)分配/找回一整塊連續(xù)的共享內(nèi)存區(qū)域;步驟830 :初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池;
步驟840 內(nèi)存池完成托管類型的管理與恢復(fù)。其中,步驟820和步驟830由MTO接口層(MT0A1 locator)提供的初始化接口Initialize (ShmKey)負(fù)責(zé)執(zhí)行。具體包括以下步驟步驟al :計(jì)算支持所有托管到MTO系統(tǒng)的類型和類型組所需要的共享內(nèi)存總大小(TotalSize)。其中,所述TotalSize由兩部分組成其一、是共享內(nèi)存元數(shù)據(jù)對(duì)象大小(sizeof (CSharedMem)),其二、需要遍歷所有類型組,根據(jù)類型組的記錄項(xiàng),計(jì)算為該類型組分配的固定大小內(nèi)存池所占用的空間(sizeof (CObjMng) +sizeof (CIdx)*Count+MaxTypeSize*Count)。步驟a2 :根據(jù)當(dāng)前應(yīng)用進(jìn)程傳入的共享內(nèi)存ShmKey值和計(jì)算的TotalSize大小,創(chuàng)建或重新獲得共享內(nèi)存對(duì)象,并調(diào)用shmatO將獲得的共享內(nèi)存段連接到應(yīng)用進(jìn)程?!み@里,可使用Linux共享內(nèi)存操作應(yīng)用程序接口(API);使用函數(shù)shmget()的返回結(jié)果可以區(qū)分是新創(chuàng)建還是找回已存在的共享內(nèi)存對(duì)象,并利用函數(shù)shmatO將獲得的共享內(nèi)存對(duì)象attach到應(yīng)用進(jìn)程;其中,shmgetO為創(chuàng)建/找回共享內(nèi)存的函數(shù)。此時(shí),(ShmKey, TotalSize)標(biāo)識(shí)的共享內(nèi)存對(duì)象在進(jìn)程中首地址為pAddr,共享內(nèi)存總大小為TotalSize。步驟a3 :在共享內(nèi)存首部創(chuàng)建CSharedMem對(duì)象,并記錄共享內(nèi)存元數(shù)據(jù)。具體的,填充CSharedMem對(duì)象數(shù)據(jù)項(xiàng),根據(jù)步驟a2的返回結(jié)果設(shè)置共享內(nèi)存模式(Mode)為 SHM_INIT、或 SHM_REC0VER ;Mode 為 SHM_REC0VER 模式時(shí),需設(shè)置 Offset 作為本次與上次attach共享內(nèi)存首地址pAddr的差值。步驟a4 :遍歷每個(gè)類型組,逐一為每個(gè)類型組在共享內(nèi)存區(qū)域映射固定大小內(nèi)存池,將映射關(guān)系保存在MTO接口層中,并完成內(nèi)存池上對(duì)象的初始化或恢復(fù)工作。這里,MTO接口層為每個(gè)類型組記錄下類型組與共享內(nèi)存區(qū)域管理頭部CObjMng的映射關(guān)系。無(wú)論是SHM_INIT模式還是SHM_REC0VER模式,類型組到對(duì)應(yīng)內(nèi)存池映射關(guān)系是不變的。所有內(nèi)存池根據(jù)共享內(nèi)存模式(Mode)的不同,完成相應(yīng)的操作。若Mode為SHM_INIT模式,說(shuō)明是首次創(chuàng)建新的共享內(nèi)存段,則內(nèi)存池(CObjMng)初始化所有的數(shù)據(jù)塊(CObj)均是空閑的,所有索引節(jié)點(diǎn)(CIdx)均加入FreeList,且UsedList為空值;若Mode為SHM_REC0VER模式,則內(nèi)存池遍歷UsedList中每個(gè)CIdx對(duì)象,根據(jù)各CIdx對(duì)象上記錄的Type類型,在CIdx對(duì)象對(duì)應(yīng)的數(shù)據(jù)塊區(qū)域重新placement new,完成數(shù)據(jù)區(qū)所有使用對(duì)象的自動(dòng)恢復(fù);并為對(duì)象中的每個(gè)指針數(shù)據(jù)加上Offset值,以恢復(fù)指針數(shù)據(jù);如此,即可完成共享內(nèi)存上對(duì)象的自動(dòng)恢復(fù)工作?;诠蚕韮?nèi)存,對(duì)象的創(chuàng)建、訪問(wèn)和釋放均是通過(guò)操作接口完成的,其中,對(duì)象創(chuàng)建接口為CreateObject (Group, Type),用于向類型組Group申請(qǐng)類型為Type的對(duì)象,并返回對(duì)象指針;對(duì)象獲取接口為GetObject (Group, ObjID),用于向類型組Group請(qǐng)求獲取下標(biāo)為ObjID的對(duì)象,并返回對(duì)象指針;對(duì)象釋放接口為DestroyObject (Group, ObjID),用于向類型組Group請(qǐng)求釋放下標(biāo)為ObjID的對(duì)象。具體的,通過(guò)對(duì)象創(chuàng)建接口完成的對(duì)象創(chuàng)建包括以下步驟步驟bl :通過(guò)MTO接口層查找類型組Group映射的內(nèi)存池的頭部COb jMng ;
步驟b2 :從FreeList找到空閑數(shù)據(jù)塊,根據(jù)類型Type執(zhí)行placement new創(chuàng)建對(duì)象,將對(duì)應(yīng)的索引塊CIdx從FreeList刪除并加入U(xiǎn)sedList ;步驟b3 :設(shè)置CIdx的附著Obj對(duì)象指針(pAttachedOb j)指向數(shù)據(jù)塊上的CObj派生對(duì)象首地址;步驟b4 :返回類型為Type的Obj對(duì)象指針。具體的,通過(guò)對(duì)象獲取接口完成的對(duì)象獲取包括以下步驟步驟Cl :通過(guò)MTO接口層查找類型組Group映射的內(nèi)存池的頭部COb jMng ;步驟c2 :根據(jù)下標(biāo)ObjID直接查找對(duì)應(yīng)索引塊CIdx ;步驟c3 :檢查CIdx使用狀態(tài)并返回對(duì)應(yīng)的CObj對(duì)象指針。
具體的,通過(guò)對(duì)象釋放接口完成的對(duì)象釋放包括以下步驟步驟dl :通過(guò)MTO接口層查找類型組Group映射的內(nèi)存池的頭部COb jMng ;步驟d2 :根據(jù)下標(biāo)ObjID直接查找對(duì)應(yīng)索引塊CIdx ;步驟d3 :檢查CIdx使用狀態(tài),并將CIdx從UsedList刪除,重新加入FreeList,標(biāo)識(shí)CIdx對(duì)應(yīng)的數(shù)據(jù)塊空閑。下面以一個(gè)游戲服務(wù)器應(yīng)用場(chǎng)景為例進(jìn)一步說(shuō)明本發(fā)明的應(yīng)用。本實(shí)施例中,游戲服務(wù)器需要支持3000個(gè)游戲用戶類(CPlayer)對(duì)象、2000個(gè)房間類(CRoom)對(duì)象、以及2000個(gè)各種游戲邏輯類對(duì)象,包括多人舞蹈基類CGameLogic、傳統(tǒng)舞蹈模式CGLTradition、四鍵模式CGLFourKey、傳統(tǒng)舞蹈與四鍵混合模式GGLMix、情侶四鍵模式CGLLoversFourKey。在實(shí)際應(yīng)用中,需要先設(shè)置類型組,包括游戲用戶組、房間組和游戲邏輯組的待托管類型組;其中,游戲用戶組GR0UP_PLAYER,用于托管單一游戲用戶類CPlayer的對(duì)象的分配、獲取和釋放,最大可支持3000個(gè)游戲用戶對(duì)象;房間組GR0UP_R00M,用于托管單一房間類CRoom的對(duì)象的分配、獲取和釋放,最大可支持2000個(gè)房間對(duì)象;游戲邏輯組GR0UP_GAMEL0GIC,用于托管多種游戲邏輯類對(duì)象的分配、獲取和釋放,最大可支持2000個(gè)游戲邏輯對(duì)象,可以是上述類型組中任意游戲邏輯類型。這里,上述需要MTO系統(tǒng)托管的類型,都必須直接或者間接地繼承自CObj基類,類型的繼承體系示意如圖10所示。所述CObj繼承是指在多繼承時(shí),左支是第一父類、右支是第二父類;如,Clovers不屬于CObj繼承體系,則情侶四鍵模式CGLLoversFourKey的第一父類是情侶邏輯CLovers、第二父類是多人四鍵模式CGLFourKey ;當(dāng)然,MTO系統(tǒng)也支持CGLLoversFourKey的第一父類是CGLLoversFourKey、第二父類是Clovers的情況。在菱形繼承時(shí),可采用虛繼承方式,也可不采用虛繼承方式。本實(shí)施例中,調(diào)用MTORegister提供的托管類型和類型組注冊(cè)接口包括步驟A :使用 MTORegister 中的 RegisterType(Type)接口,注冊(cè)需要托管的 CObj派生類型;其中,所述CObj 派生類型包括 CPlayer、CRoom、CGameLogic、CGLTrandition、CGLFourKey> CGLMix、CGLLoversFOurKey。這里,因?yàn)镃lovers不屬于本實(shí)施例需要托管到MTO系統(tǒng)的類型,更不屬于CObj繼承體系,所以不用注冊(cè)進(jìn)來(lái)。步驟B :使用MTORegister中的RegisterGroup(Group)接口,注冊(cè)應(yīng)用需求的類型組;
其中,所述類型組包括GR0UP_PLAYER、GR0UP_R00M、GR0UP_GAMEL0GIC。步驟C :使用 MTORegister 中的 BindTypeToGroup (Group, Type)接口,建立類型與對(duì)應(yīng)類型組的映射關(guān)系;這里,根據(jù)應(yīng)用類型組劃分,對(duì)應(yīng)的類型綁定到對(duì)應(yīng)的類型組中,例如BindTypeToGroup(GROUP_PLAYER, CPlayer)等。本實(shí)施例中,MTO接口層初始化為應(yīng)用指定ShmKey數(shù)值,調(diào)用MTO接口層中的Initialize (Key)接口。本實(shí)施例中,應(yīng)用對(duì)對(duì)象訪問(wèn)時(shí),應(yīng)用可直接訪問(wèn)MTO接口層為對(duì)象訪問(wèn)所提供的 CreateOb ject、GetObject 和 DestroyObject 接口。下面以游戲邏輯組 GR0UP_GAMEL0GIC 為例,說(shuō)明MTO系統(tǒng)對(duì)托管類型對(duì)象分配、獲得和釋放時(shí)內(nèi)存池的狀態(tài)。內(nèi)存池的初始狀態(tài)如圖11所示,所有對(duì)象均在FreeList中,UesdList中沒(méi)有元素。對(duì)象創(chuàng)建過(guò)程中,按照順序向游戲邏輯組依次申請(qǐng)CGLFourKey、CGLMix和CGLLoversFourKey對(duì)象后,游戲邏輯組的內(nèi)存池狀態(tài)如圖12所示。對(duì)象獲取過(guò)程中,以圖12的狀態(tài)為例,對(duì)對(duì)象的引用都是通過(guò)游戲邏輯組和數(shù)組下標(biāo)的方式,直接索引到對(duì)象;MT0接口層為了支持類型擴(kuò)展,均通過(guò)GetOject(Group,ObjID)接口返回CIdx附著的CObj*指針,需要應(yīng)用dynamic_cast向下轉(zhuǎn)型為正確的特定類型使用。對(duì)象釋放過(guò)程中,按照順序從游戲邏輯組依次釋放下標(biāo)為O(CGLFourKey)和下標(biāo)為2 (CGLLoversFourKey)的對(duì)象后,內(nèi)存池的狀態(tài)如圖13所示。當(dāng)進(jìn)程停止或Crash后,進(jìn)程重新啟動(dòng),需要完成對(duì)象恢復(fù)時(shí),重新執(zhí)行所有的托管類型和類型組的注冊(cè)過(guò)程及接口初始化,MTO系統(tǒng)會(huì)自動(dòng)完成共享內(nèi)存的獲取并重新attach進(jìn)程,進(jìn)而完成共享內(nèi)存上對(duì)象狀態(tài)的上下文恢復(fù)。本發(fā)明基于Linux操作系統(tǒng)和gcc/g++(4. I. 2)編譯器平臺(tái)實(shí)現(xiàn),但在UNIX-Like操作系統(tǒng),如UNIX、HP-UNIX、Solaris、BSD系列;以及Win32/VC8平臺(tái)均可以使用類似的共享內(nèi)存的對(duì)象管理與恢復(fù)方法。以上所述,僅為本發(fā)明的較佳實(shí)施例而已,并非用于限定本發(fā)明的保護(hù)范圍,凡在本發(fā)明的精神和原則之內(nèi)所作的任何修改、等同替換和改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。
權(quán)利要求
1.一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法,其特征在于,該方法包括 注冊(cè)托管到MTO系統(tǒng)的類型和類型組,并建立類型與類型組之間的關(guān)聯(lián)關(guān)系;根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池;由內(nèi)存池完成托管類型的管理與恢復(fù)。
2.根據(jù)權(quán)利要求I所述的方法,其特征在于,所述建立類型組與其對(duì)應(yīng)的共享內(nèi)存區(qū)域的映射關(guān)系包括 al、計(jì)算支持所有托管到MTO系統(tǒng)的類型和類型組所需要的共享內(nèi)存總大小(TotalSize); a2、根據(jù)當(dāng)前應(yīng)用進(jìn)程傳入的共享內(nèi)存關(guān)鍵值ShmKey和計(jì)算的TotalSize大小,創(chuàng)建或重新獲得共享內(nèi)存對(duì)象,并調(diào)用shmatO將獲得的共享內(nèi)存段連接到應(yīng)用進(jìn)程; a3、在共享內(nèi)存首部創(chuàng)建CSharedMem對(duì)象,并記錄共享內(nèi)存元數(shù)據(jù); a4、遍歷每個(gè)類型組,逐一為每個(gè)類型組在共享內(nèi)存區(qū)域映射固定大小內(nèi)存池,保存映射關(guān)系并完成內(nèi)存池上對(duì)象的初始化或恢復(fù)。
3.根據(jù)權(quán)利要求I所述的方法,其特征在于,所述對(duì)共享內(nèi)存的管理為通過(guò)對(duì)象創(chuàng)建接口完成的對(duì)象創(chuàng)建; 所述對(duì)象創(chuàng)建包括查找類型組映射的內(nèi)存池的頭部CObjMng ;從空閑列表FreeList找到空閑索引塊CIdx [i],根據(jù)類型Type在對(duì)應(yīng)空閑數(shù)據(jù)塊CObj [i]的首地址執(zhí)行placement new創(chuàng)建對(duì)象,對(duì)應(yīng)的索引塊CIdx[i]從FreeList刪除,并加入使用列表UsedList 中。
4.根據(jù)權(quán)利要求I所述的方法,其特征在于,所述對(duì)共享內(nèi)存的管理為通過(guò)對(duì)象獲取接口完成的對(duì)象獲??; 所述對(duì)象獲取包括查找類型組映射的內(nèi)存池的頭部CObjMng ;根據(jù)請(qǐng)求下標(biāo)i直接查找對(duì)應(yīng)索引塊CIdx[i];檢查CIdx[i]使用狀態(tài)并返回對(duì)應(yīng)的數(shù)據(jù)塊CObj [i]。
5.根據(jù)權(quán)利要求I所述的方法,其特征在于,所述對(duì)共享內(nèi)存的管理為通過(guò)對(duì)象釋放接口完成的對(duì)象釋放; 所述對(duì)象釋放包括查找類型組映射的內(nèi)存池的頭部CObjMng ;根據(jù)請(qǐng)求下標(biāo)i直接查找對(duì)應(yīng)索引塊CIdx[i];檢查CIdx[i]使用狀態(tài),并將CIdx[i]從UsedList刪除,重新加入FreeList0
6.根據(jù)權(quán)利要求I至5任一項(xiàng)所述的方法,其特征在于,該方法進(jìn)一步包括引入MTO系統(tǒng)抽象基類CObj,所有托管到MTO系統(tǒng)的類型均必須直接或間接派生自CObj,支持單繼承或多繼承方式。
7.根據(jù)權(quán)利要求I至5任一項(xiàng)所述的方法,其特征在于,為每個(gè)注冊(cè)類型組分配的共享內(nèi)存區(qū)域包括管理頭、索引域和數(shù)據(jù)域。
8.一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)系統(tǒng),其特征在于,該系統(tǒng)包括:ΜΤ0托管類型/類型組注冊(cè)模塊、MTO接口層、以及MTO共享內(nèi)存管理模塊;其中, 所述MTO托管類型/類型組注冊(cè)模塊,用于記錄所有托管到MTO系統(tǒng)的類型和類型組的元數(shù)據(jù)信息,并建立類型和類型組之間的關(guān)聯(lián)關(guān)系; 所述MTO接口層,用于建立類型和類型組與其對(duì)應(yīng)的共享內(nèi)存區(qū)域的映射關(guān)系; 所述MTO共享內(nèi)存管理模塊,用于對(duì)MTO接口層確定的、對(duì)應(yīng)各個(gè)類型組的共享內(nèi)存區(qū)域進(jìn)行管理。
9.根據(jù)權(quán)利要求8所述的系統(tǒng),其特征在于,所述所有托管到MTO系統(tǒng)的類型均必須直接或間接派生自引入的MTO系統(tǒng)抽象基類CObj,支持單繼承或多繼承方式。
10.根據(jù)權(quán)利要求8或9所述的系統(tǒng),其特征在于,所述MTO共享內(nèi)存管理模塊包括共享內(nèi)存自身元數(shù)據(jù)記錄部分、以及固定大小內(nèi)存池管理部分; 相應(yīng)的,所述共享內(nèi)存包括共享內(nèi)存元數(shù)據(jù)空間和內(nèi)存池空間。
全文摘要
本發(fā)明公開了一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)方法,包括注冊(cè)托管到MTO系統(tǒng)的類型和類型組,并建立類型與類型組之間的關(guān)聯(lián)關(guān)系;根據(jù)所有注冊(cè)類型組信息分配/找回一塊連續(xù)的共享內(nèi)存區(qū)域;初始化/恢復(fù)所分配的共享內(nèi)存區(qū)域,并為每個(gè)類型組在共享內(nèi)存區(qū)域映射內(nèi)存池;由內(nèi)存池完成托管類型的管理與恢復(fù)。本發(fā)明還同時(shí)公開了一種基于共享內(nèi)存的對(duì)象管理與恢復(fù)系統(tǒng),采用本發(fā)明,能夠?qū)崿F(xiàn)共享內(nèi)存上對(duì)象的高效管理與自動(dòng)恢復(fù)。
文檔編號(hào)G06F17/30GK102955817SQ201110252490
公開日2013年3月6日 申請(qǐng)日期2011年8月30日 優(yōu)先權(quán)日2011年8月30日
發(fā)明者伍洋, 韓勇, 胡健 申請(qǐng)人:騰訊數(shù)碼(深圳)有限公司