C 記憶體池的設計及思想

2021-09-26 02:50:55 字數 1429 閱讀 2997

預設的分配和釋放記憶體演算法自然也考慮了效能,然而這些記憶體管理演算法的通用版本為了應付更複雜、更廣泛的情況,需要做更多的額外工作。而對於乙個具體的應用程式來說,適合自身特定的記憶體分配釋放模式的自定義記憶體池則可以獲得更好的效能。

應用程式自定義的記憶體池根據不同的使用場景有不同的型別

a.從執行緒安全角度記憶體池可分為單執行緒記憶體池和多執行緒記憶體池

b.從記憶體池可分配記憶體單元大小的角度可以將記憶體池分為固定記憶體池和可變記憶體池

應用程式可以通過系統的記憶體分配呼叫預先一次性申請適當大小的記憶體作為乙個記憶體池,之後應用程式自己對記憶體的分配和釋放則通過這個記憶體池來完成就可以了。只有當記憶體池的大小需要動態擴充套件時,才需要再呼叫系統的記憶體分配函式,其它時候對記憶體的一切操作都在應用程式的掌控之中。

固定記憶體池由一系列固定大小的記憶體塊組成,每乙個記憶體塊又包含了固定數量和大小的記憶體單元。如上圖,該記憶體池一共包含4個記憶體塊,乙個記憶體塊包含乙個記憶體塊頭和三個記憶體單元,在記憶體池初次生成時,只向系統申請了乙個記憶體塊,返回的指標作為整個記憶體池的頭指標。之後隨著應用程式對記憶體的不斷需求,記憶體池判斷需要動態擴大是,才再次向系統申請新的記憶體塊,並把這些記憶體塊再通過指標連線起來。由於大小是固定的的,所以分配的速度比較快;而對於應用程式來說,其記憶體池開闢了一定大小,記憶體池內部卻還有剩餘的空間。

如上圖,我們將第四個記憶體塊放大來看,其中包含乙個記憶體池塊頭資訊和3個大小相等的記憶體單元。假如記憶體單元1和記憶體單元2是空閒的,記憶體單元2已經被分配。當應用程式需要通過該記憶體池分配乙個單元大小的記憶體時,只需要簡單遍歷所有的記憶體池塊頭資訊,快速定位還有空閒記憶體單元的那個記憶體池快。然後根據該塊的塊頭資訊直接定位到第乙個空閒的單元位址,把這個位址返回,並且標記下乙個空閒單元即可;當應用程式釋放某乙個記憶體池單元時,直接在對應的記憶體池塊頭資訊中標記該記憶體單元即可。

針對特殊情況,如需要頻繁的分配釋放固定大小的記憶體物件時,不需要複雜的分配演算法和多執行緒保護。也不需要維護記憶體空間標的額外開銷,從而獲得比較高的效能。

由於開闢了一定數量的連續記憶體空間作為記憶體池塊,因而一定程度上提高了程式區域性性,提公升了程式效能。

比較容易控制頁邊界對齊和記憶體位元組對齊,沒有記憶體碎片的問題。

記憶體池的內部構造

class memorypool

;

struct memoryblock

static void operator delete(void *p,size_t)

memoryblock(ushort ntypes=1,ushort nunitsize=0);//

~memoryblock(){}//記憶體塊不做析構釋放記憶體,交給記憶體池統一管理

};

記憶體池 C 記憶體池

c c 下記憶體管理是讓幾乎每乙個程式設計師頭疼的問題,分配足夠的記憶體 追蹤記憶體的分配 在不需要的時候釋放記憶體 這個任務相當複雜。1.呼叫malloc new,系統需要根據 最先匹配 最優匹配 或其他演算法在記憶體空閒塊表中查詢一塊空閒記憶體,呼叫free delete,系統可能需要合併空閒記...

記憶體池 程序池 執行緒池介紹及執行緒池C 實現

平常我們使用new malloc在堆區申請一塊記憶體,但由於每次申請的記憶體大小不一樣就會產生很多記憶體碎片,造成不好管理與浪費的情況。記憶體池則是在真正使用記憶體之前,先申請分配一定數量的 大小相等 一般情況下 的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊...

記憶體池設計(五)

將以上 組裝,並自己設計累 user 來測試這個記憶體池 include define mempool alignment 8 對齊長度 using namespace std 記憶體塊及其資訊表 memory block templatestruct memoryblock cout 呼叫記憶體塊...