在象通訊系統中的基站這樣的複雜嵌入式系統中,對於記憶體管理模組的效率具有很高的要求,因此記憶體管理模組的演算法很有講究。講究在於,不僅要考慮演算法的效率,還要兼顧演算法是否會帶來大量的記憶體碎片以及如何進行記憶體碎片合併。正因如此,這類嵌入式系統軟體大多會對記憶體管理模組根據業務特點進行適當的優化。
優化的方式無外乎引入記憶體池,或對堆管理模組引入新的演算法加以優化,然而這些方法除了引入了一定的演算法複雜度外,仍存在不小的改善空間。藉此,作者想提出一種面向業務流的記憶體管理演算法與大家共同**。
為了討論的方便性,我們假設某虛擬系統存在如下的業務流順序圖。圖中的三個模組只是代表性的,它們即可以指以訊息為通訊手段的三個任務,也可以指存在函式呼叫關係的三個模組。圖中的紅色訊息表示存在處理的過程中需進行記憶體分配的操作,並假設所分配出來的內存在訊息的後續處理中需要用到。比如,處理msga時所分配的記憶體可能需要被moduleb和modulec使用,且該內存在處理完msga後需要釋放。值得一提的是,這個虛擬系統存在大量的併發業務流需要處理(這好比機站中存在多個**呼叫信令需要同時處理)。
對於這樣的業務流,最為傳統的記憶體使用方法是分別在處理msga和msgb時呼叫記憶體分配函式獲取記憶體,並將所獲得的記憶體指標通過訊息攜帶的方式傳遞給後續模組處理。當系統複雜(乙個訊息的後續處理模組數非常多),且所分配的內存在大小上存在不小差別時,分配和釋放記憶體的效率及記憶體碎片問題或成為系統的瓶頸,加之記憶體的分配與釋放功能是分散在不同的模組中的,因而容易產生記憶體洩漏。
現在讓我們跳出這種使用記憶體的傳統思維,站在業務流的角度重新審視記憶體的使用方法。不難發現,對於乙個業務流,處理msga和msgb所分配的記憶體儘管存在分配時機上的區別,但它們都共同服務於同一業務流。既然如此,我們為何不將記憶體的分配與釋放時機放在業務流的開始與結束處呢?比如,在處理msga時將msgb所需的記憶體也分配好,所有分配的記憶體也可以在業務流結束後共同釋放。採用這種方式需要解決乙個問題,既在處理msga時需要知道處理msgb時所需分配記憶體的大小。顯然,不能簡單地將處理msgb的部分功能挪到處理msga的功能塊中,因為這可能會破壞程式結構。簡易的解決方法可以通過犧牲一定的記憶體獲得 — 通過分析業務流,我們可以知道處理某訊息所需分配記憶體的最大值,進而用那個最大值作為在處理msga時所需提前分配的數量。(注:如果記憶體的大小存在很大的差異,作者建議結合採用傳統方法,而非完全採用後面將要談到的方法)
至此,我們邁出了很重要的一種思路轉變,為了獲得方便的實現方法我們仍需更進一步。如果乙個業務流中各處所需分配的記憶體大小能預先以取最大值的方式確定下來加以規劃,我們就可以通過一定的資料結構來表達,如下圖所示。
#define max_size_for_msga 32#define max_size_for_msgb 128
typedef
struct
business_flow_memory_t;
#define config_max_business_flow_supported 900
business_flow_memory_t g_memory_pool [config_max_business_flow_supported];
相信圖中的前部分**很是直截了當,後部分**則假設系統最多同時支援900個業務流需要處理。當乙個新的業務流需要處理時(在這裡的例子中,處理msga時),直接從g_business_memory_pool陣列中獲取乙個元素,以作處理整個業務流所需的全部記憶體(可以設想,這一記憶體會在業務流的不同處理階段被使用);當結束乙個業務流時(在這裡的例子中,處理完msga後),則可以通過一次性地釋放該元素從而完成記憶體釋放。顯然,陣列元素的獲取與釋放需要為這提供相應的函式,且對元素的管理可以考慮引入鍊錶等方法以提高管理效率。這部分內容我們在此不展開。
致此相信讀者已了解面向業務流記憶體管理演算法的機理了。作為結束,我們應總結一下這一演算法的優缺點。優點有:一,分配與釋放非常高效,且不會隨著系統的執行而產生任何記憶體碎片;二,很容易杜絕記憶體洩漏。缺點有:一,由於每處使用的記憶體需以最大值進行規劃,存在一定的記憶體浪費;二,當以記憶體所需最大值進行規劃存在嚴重的記憶體浪費時,該演算法存在適用性問題。再囉嗦一下,如有適用性問題時,請運用傳統使用記憶體的方法(呼叫malloc/free)與這裡所主張的方法相結合加以解決。
一種面向業務流的記憶體管理演算法
在象通訊系統中的基站這樣的複雜嵌入式系統中,對於記憶體管理模組的效率具有很高的要求,因此記憶體管理模組的演算法很有講究。講究在於,不僅要考慮演算法的效率,還要兼顧演算法是否會帶來大量的記憶體碎片以及如何進行記憶體碎片合併。正因如此,這類嵌入式系統軟體大多會對記憶體管理模組根據業務特點進行適當的優化。...
常用的記憶體管理演算法的簡要介紹
主要是介紹一下常用的記憶體管理演算法以及相關的資料結構.三種型別 size medium 1 sequential fit size 包括first fit,next fit,以及best fit 這種演算法的實現基本來說都是基於乙個雙向鍊錶或者迴圈鍊錶來儲存所有的free memory.而且一般都...
一種巧妙的記憶體池演算法 HeapBlock
在乙個簡單的gui庫中看到的演算法,非常巧妙,適用於需要頻繁分配和釋放相同大小資料塊的情況,如gui庫中的視窗結構,socket結構等,演算法額外開支極小。cpp view plain copy print?typedef dword hblockheap typedef unsigned char...