memory pool 的高效實現

2021-05-09 11:43:41 字數 1759 閱讀 8080

malloc

可以分配任意大小的記憶體,因此,在

malloc

內部,儲存了一些簿記資訊(至少有乙個包含記憶體塊尺寸的資訊)。呼叫

free

時,可以正確釋放。

為了減少這些簿記開銷,可以使用

memory pool

。根據使用情境,可以分為兩種:

1.只分配固定大小的記憶體塊,速度最快(

normal path約10

條機器指令)。

2.可分配不同大小的記憶體塊,速度稍慢,但比

malloc

快得多,也無簿記開銷。

以下將分別說明

mpool

可分配不同尺寸的記憶體。大多數時刻,都在內部分配。

銷毀mpool

時,會自動釋放在

mpool

中未釋放的記憶體。

mpool

內部有乙個包含多個不同尺寸

fixed_mpool

的array

,根據請求分配的記憶體大小,直接索引到相應的

fixed_mpool

來分配乙個單元(

cell

)。通過定義巨集febird_mpool_allow_big_block

,就允許大於

max_cell_size

的記憶體分配。在這種情況下,使用標準的

malloc

分配記憶體,分配出去的記憶體有額外簿記(用雙向鍊錶串起來),以便在銷毀

mpool

時自動釋放。

fixed_mpool

尺寸固定的記憶體池,一旦建立,該記憶體池只能分配固定尺寸的記憶體單元(

cell

)。這在很多情況下都適用,例如鍊錶結點、樹節點、圖結點、自定義的結構、等等。

用於stl

的map/set/list

再適合不過了——但是不能用於

vector/deque

等需要分配可變尺寸的容器。

fixed_mpool

內部的多個

chunk

使用陣列,類似

std::vector

,inextchunk

相當於vector.size

,nchunks

相當於vector.capacity

,每次空間不夠時擴張一倍。使用陣列,而不是鍊錶,有以下好處:

1.有助於對齊——如果

chunk_allocator

是對齊(對齊

>=32

時)分配的,而

chunk

使用鍊錶組織,就會在

chunk

開始處預留乙個

chunk

頭部,這會導致不對齊。

2.如果

cell_size

也剛好較大且整除

chunk_size

,使用鍊錶就會浪費將近乙個

cell

(cell_size – chunk_header_size

)。3.

如果不把連線資訊儲存在

chunk header

,就需要另外分配

chunk

結點,而分配

chunk

結點又需要其它記憶體分配函式。

空閒表使用單鏈表,因此,理論上每個

cell

最小必須能容納乙個指標,

32位系統式

4位元組,

64位系統式

8位元組,實現中使用

8位元組作為最小值。

關於Memory Pool的一些想法及實現

在 effective c second edition 中item 10 write operator delete if you write operator new 中提到乙個memory pool技術,並給出乙個例子 void airplane operator new size t siz...

求素數的高效實現

對於給定的乙個數n,如何判斷其是否是素數呢?最簡單最直觀的方法是試除法 下面的演算法1 2 3 還有一種方法是rabin miller演算法。from 2 to n思路 從2到n 1,做取模運算n mod i 若運算結果均為 0 則 n 為素數 實現 public boolean isprimenu...

記憶體池 高效實現

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