C 實現乙個簡單記憶體池

2021-10-08 23:56:04 字數 2462 閱讀 1728

在使用記憶體池進行記憶體管理之前,通常使用new/malloc或者delete/free來申請或者釋放記憶體。在這個過程中,系統要首先查詢內部維護的記憶體空閒塊表,並且需要根據比如lru等記憶體分配演算法找到合適大小的空閒記憶體塊。如果該空閒記憶體塊過大,還需要切割成已分配的部分和較小的空閒塊。然後系統更新記憶體空閒塊表,完成一次記憶體分配。類似地,在釋放記憶體時,系統把釋放的記憶體塊重新加入到空閒記憶體塊表中。如果有可能的話,可以把相鄰的空閒塊合併成較大的空閒塊。預設的記憶體管理函式還考慮到多執行緒的應用,需要在每次分配和釋放記憶體時加鎖,同樣增加了開銷。

由此可見,當申請的記憶體塊大小不定,申請和釋放時間也不相同。 所以這個堆(連續的整個記憶體塊) 會形成零零散散的情況(稱為記憶體碎片)。當頻繁使用時會造成大量的記憶體碎片並進而降低效能;並且在堆中分配記憶體時,需要查詢查詢已分配鍊錶和空閒塊鍊錶,查詢這兩張表需要時間,所以如果申請和釋放堆記憶體比較頻繁的話,會比較浪費時間。基於上面兩點,考慮使用記憶體池的方式,進行記憶體塊的管理,減小分配和**的開銷。

記憶體池實現的步驟:

(1)首先申請一塊空間當做初始的記憶體池,這塊空間容納一部分物件。

(2)定義乙個記憶體節點為一塊鍊錶空間加上指向下一塊鍊錶節點的指標,即memory node。各個空閒的記憶體節點通過指標形成乙個鍊錶,鍊錶的每乙個記憶體節點都是一塊可供分配的記憶體空間;

(3)定義乙個指標freenodeheader為可用的空閒結點的頭指標。每當一塊memorynode被分配出去,freenodeheader下移,那麼這塊空間就認為被占用了。

(4)乙個memorynode被**,那麼就重新放入freenodeheader指向的鍊錶首位,也就是重新加入空閒鍊錶。

(5)如果空閒區不夠用了,那麼新建乙個記憶體塊,記憶體塊上有新的記憶體節點,接著進行分配就行。這也就體現出了「記憶體池」的作用。

如上圖所示,記憶體塊有指標指向這個記憶體塊的真正可以分配的記憶體空間,也就是memorynode。blockheader用於指向第乙個記憶體塊,方便對記憶體塊進行管理。freenodeheader用於真正管理記憶體節點。每次分配的時候,freenodeheader下移一位,表示這個節點被分配出去了。當歸還乙個節點,則上移一位,把這個節點插入鍊錶中就可以了。

實現的源**:

#include#include#include#includeusing namespace std;

templateclass mempool

; //freenode空閒節點結

struct freenode ;

freenode* freenodeheader;

memblock* memblockheader;

public:

mempool()

// 記憶體池析構函式,刪除每乙個記憶體塊節點

~mempool() }

//用於分配乙個可用的空閒結點

void* malloc();

//**乙個空閒結點

void free(void*);};

//分配空閒的節點

templatevoid* mempool::malloc()

newblock->data[numofobjects - 1].pnext = null;

//首次申請記憶體塊,那麼他就是第一塊

if (memblockheader == null)

else

}//返回空節點閒鍊錶的第乙個節點

void* freenode = freenodeheader;

freenodeheader = freenodeheader->pnext;

//去鎖

pthread_mutex_unlock(&mutex);

return freenode;}

//釋放已經分配的節點,直接插入freenode隊首即可

templatevoid mempool::free(void* p)

//我們用到的用於向記憶體池申請空間的類

class actualclass

void print()

//向記憶體池申請和刪除空間的方法

void* operator new(size_t size);

void operator delete(void* p);};

//定義記憶體池物件

mempoolmp;

//申請一塊大小為sizeof(actualclass)大小的空間,返回指標指向這塊空間

void* actualclass::operator new(size_t size)

//刪除這塊申請的空間

void actualclass::operator delete(void* p)

int actualclass::count = 0;

//測試記憶體池的函式

void achievemempool()

乙個簡單記憶體池實現

最近面試被問了乙個記憶體池的實現,關鍵是記憶體塊的組織,說來慚愧,由於之前沒有詳細去了解過實現,只記得作業系統上有說過空閒鍊錶的實現,即按分配的塊用鍊錶鏈結,有小塊優先,大塊優先等 後來回來認真地找了幾個記憶體池實現的技術介紹,多數是以乙個固定塊,每個塊又有固定長度的單元組成。參考了網上的一些實現方...

乙個簡單的記憶體池

為什仫要使用記憶體池?1.通常我們用new delete和malloc free來管理記憶體,可能會需要頻繁的呼叫記憶體,減少執行時間,增加效率.2.避免記憶體碎片 傳統的new delete的弊端 1.分配記憶體時要檢視空閒分割槽表,根據一定的演算法來分配,比如最佳適應演算法,最差適應演算法.然後...

乙個簡單的記憶體池

記憶體池是我們經常使用的一種池,常見的池還有程序池 執行緒池和連線池,今天我們就先討論記憶體池。首先看一下池的定義 池 池就是在初始時,申請比剛開始要使用的資源大的多的資源空間,接下來使用時,直接從池中獲取資源。記憶體池 即在初始時申請分配一定數量的。大小相等的記憶體塊留作備用,此後如有需要直接從該...