記憶體池實現

2021-06-08 20:13:00 字數 1169 閱讀 5821

記憶體池實現

話說一直想找乙個別人寫好的使用,可惜沒什麼人會拿這小東西發布,只好自寫乙個。

1.多級鍊錶分配池

我不知道這種設計的具體學名是什麼,這部分的內容也許你去看《stl原始碼分析》的有關章節更合適一些,這裡我只能用我粗陋的語言描述一下。

記憶體池,完全可以從字面上理解為從池子裡申請記憶體,釋放的時候還給池子。

最簡單的記憶體池應該是fix_pool吧,即每次分配出來的記憶體塊大小是固定的。這種池子的管理結構是乙個鍊錶,鍊錶的每乙個節點為固定大小的記憶體塊。分配的時候,直接返回鍊錶的第乙個節點,節點不足時,從系統申請大塊記憶體分成多個節點加入鍊錶;釋放的時候更簡單,將釋放的記憶體加入煉表頭。

假設fix_pool的fix size = 128,那麼記憶體池可以為128byte以下的任意大小的請求進行分配,但是這樣做相當浪費呢,於是unfix_pool就在此基礎上出現了。

由多個分配大小不同的fix_pool所組成的記憶體池就叫做多級鍊錶分配池,我是這麼定義的。

常規上會定義8,16,24,32,...,112,120,128這些分配大小,共16級。分配或者釋放的時候,判斷請求的大小在哪一級別上,用該級別的fix_pool鍊錶進行分配或者釋放。

2.洩漏檢測

當所有的分配都經過你的手的時候,洩漏檢測什麼的再簡單不過了。

找個地方把分配的東西記錄下來,釋放的時候把記錄去掉。程式退出的時候還存在的分配記錄就是洩漏了。

我個人選用的方法是給每乙個分配請求多分配一些記憶體,用來記錄分配的資訊,並將這部分資訊用雙向鍊錶串起來。釋放的時候對釋放的指標做一下指標偏移就可以找到資訊記錄並移出雙向鍊錶。

這個方法的開銷是常數級的,不過無法處理重複刪除的問題。

3.operater new

要把你的記憶體池應用到每乙個角落,需要定義operator new和operator delete。

void

*operator

new(size_t) 

throw

(std::bad_alloc);

void

operator

delete(

void*p)

; 但是這還不夠,誰也不想看到一堆洩漏資訊而找不到洩漏的位置,因此還需要定義帶附加引數的operator。

對於placement new而言,operator new和operator delete是必須的,無法省略。

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

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

記憶體池 高效實現

記憶體池主要分為三個部分 class buffer t,class bufferpool t,class mempool t 1.class mempool t 記憶體開闢與釋放的介面,既可以通過記憶體池開闢釋放或者在超過記憶體池最大記憶體分配大小時,通過系統進行開闢與釋放。2.class buff...

記憶體池實現示例

1.模板類定義 使用了模板以適應不同物件的記憶體需求,記憶體池中的記憶體塊則是以基於鍊錶的結構進行組織 static void operator delete void dp private static void memalloc cur 0 qdebug memalloc static unsi...