簡單的記憶體池實現

2021-08-11 05:56:25 字數 3196 閱讀 2624

記憶體池是用來改善new/delete記憶體管理機制可能造成的執行效率低下問題的一種技術

經典的記憶體池技術,是用一種用於分配大量大小相同的小物件技術,加快記憶體分配或者釋放的過程。

在看書的過程中,我對簡單的實現乙個記憶體池的實現理解是:

1、讓我們在堆上面申請到的記憶體是連續的。

2、我們放在記憶體池中的某個物件,當我們delete它後,我們要再次申請記憶體的時候,就在剛剛delete的那個位置重新申請,而不是在記憶體的某個位置申請。

3、使用多大記憶體就申請多大的記憶體存放在記憶體池。

根據以上條件來實現,則可以通過乙個陣列鍊錶來實現,達到上面的第乙個條件;第二個條件,我們通過記憶體塊指標與記憶體節點指標的操作來實現;第三個條件,通過模板來實現。

(**與書上的**相差不大,差別就在於鍊錶指向的順序,與新增了結構體的建構函式)

**:

//my_mempool.h

//模板引數為物件的size,與數目

template

class mempool

};//mmemnode是記憶體塊節點,預設存放20個物件

struct memnode

};memnode *memheader; //指向記憶體塊第乙個節點

freenode *freeheadr;//指向自由記憶體的頭節點

const

int memblocksize;//記憶體塊大小

const

int nodesize;//申請的節點大小

public:

//每個節點除了我們物件本身的大小,還要加上每個節點中的指標大小

mempool() :nodesize(objectsize + sizeof(freenode*)), memblocksize(sizeof(memnode*) + objectnumsize*(objectsize + sizeof(freenode*)))

~mempool()

}//測試每個節點大小是否與初始化nodesize相同

void printobjectsize()

void* malloc();

void

free(void* ptr);

};

malloc申請記憶體的過程是,判freehead也就是記憶體塊中是否還有自由節點,若沒有則申請乙個記憶體塊如下**中的memblock,然後初始化memblock的自由節點鍊錶與freeheadr,並把memblock加入記憶體塊鍊錶管理。然後返回指向freeheadr的指標,也就意味著我們占用了這塊記憶體節點,然後freeheadr指向下乙個節點。

template

void * mempool::malloc()

void *temp = freeheadr;

freeheadr = freeheadr->next;

return temp;

}

free的過程就是把原來占用節點重新加入放回自由節點中,將要free的指標設定為自由節點頭指標,而原先的freeheadr則為該free的指標的next,在下一次malloc的時候直接返回該指標則達到了申請的記憶體位址為上一次銷毀的記憶體的位址,例如,p1->p2->freeheadr,我們free(p1)後,就成了p2->原來的freeheadr,p1->原來的freeheadr,而當前的freeheadr=p1,在下次malloc的時候,就返回p1的位址,然後malloc的時候freeheadr=freeheadr->next,也就是p1與p2指向的地方即原先的freeheadr處。

template

void mempool::free(void *ptr)

———————————————–main.cpp————————————————–

class b 

void show()

void* operator

new(size_t size);

void

operator

delete(void* p);

};//過載new

void * b::operator

new(size_t size)

//過載delete

void b::operator

delete(void* p)

class thepool ;

int b::m_count = 0;

mempool thepool::mp;

int main()

結果:

從結果我們可以看到,b的型別大小為20,加上指標則為24,我們申請的記憶體池是乙個記憶體塊儲存兩個物件,所以p1與p2相差的24,由於只存放兩個,所以申請p3的時候又申請了乙個記憶體塊,所以p3與p2之間的距離差很大。

---

----

----

----

----

----

----

----

----

----

----

----

在寫**的時候碰上的問題--

----

----

----

----

----

----

----

----

----

----

----

-

由於c++基礎不紮實,不清楚可以使用模板引數作為陣列大小(動態解析機制),我看到用模板裡面的引數作為陣列的大小的時候,我感覺編譯不能通過,一般陣列大小都是使用常量表示式,而c++模板可以推導出值,相當於引數的值可以推導出來,相當於這些值是常量表示式。。不知道是不是這麼理解。。

然後因為用模板引數作為陣列大小,在寫的時候,下面**在vs2015中,memblock顯示沒有呼叫的成員,但是按邏輯寫下去是可以執行的,可能這與動態解析有關。

template

void * mempool::malloc()

void *temp = freeheadr;

freeheadr = freeheadr->next;

return temp;

}

記憶體池 簡單的記憶體池的實現

當頻繁地用malloc申請記憶體,然後再用free釋放記憶體時,會存在兩個主要問題。第乙個問題是頻繁的分配釋放記憶體可能導致系統記憶體碎片過多 第二個問題是分配釋放記憶體花費的時間可能比較多 這個問題不太明顯 這個時候我們就可以考慮使用記憶體池了。最樸素的記憶體池思想就是,首先你向系統申請一塊很大的...

記憶體池簡單實現(一)

記憶體池就是在程式啟動時,預先向堆中申請一部分記憶體,交給乙個管理物件。在程式執行中,需要時向管理物件 借 不需要時 還 給管理物件。原理很簡單,關鍵是怎樣才能高效地 借 還 在c s伺服器中,需要頻繁地收發資料報。而資料報的記憶體採用原始的new delete模式,會大大降低伺服器效能,所以想到了...

最簡單的記憶體池 原理與實現

記憶體池的主要作用,簡單地說來,便是提高記憶體的使用效率。堆記憶體的申請與釋放 new delete及malloc free 涉及複雜的記憶體分配演算法,相比由簡單cpu指令支援的棧記憶體的申請與釋放,則是慢上了數量級。另一方面,棧的大小是有限制的,在需要大量記憶體的操作時,堆的使用是必要的。當然,...