C STL記憶體池

2022-05-02 10:15:12 字數 2460 閱讀 5149

記憶體池出現原因:記憶體碎片

首先我們需要明確, 記憶體池的目的到底是什麼?  首先你要知道的是, 我們每次使用new t來初始化型別t的時候, 其實發生了兩步操作,

乙個叫記憶體分配, 這一步使用的其實不是new而是operator new(也可以認為就是c語言中的malloc), 這一步是直接和作業系統打交道的, 作業系統可能需要經過相對繁瑣的過程才能將一塊指向空閒記憶體的指標返回給使用者, 所以這也是new比較耗時的一部分,

而第二步就是使用建構函式初始化該記憶體, 這是我們比較熟悉的.

既然記憶體分配耗時, 那我們很容易想到的就是一次性分配一大塊記憶體, 然後在使用者需要的時候再劃分其中一部分給使用者, 這樣的話,一次分配, 多次使用, 自然而然提高了效率, 而用來管理這所謂的一大塊記憶體的資料結構, 也就是今天我們要說的記憶體池.

另外乙個好處在於, 頻繁地使用new將導致系統記憶體空間碎片化嚴重, 容易導致的後果就是很難找到一塊連續的大塊記憶體, 造成記憶體碎片(非連續),空間利用率低. 

內碎片是指分配給作業的儲存空間中未被利用的部分,外碎片是指系統中無法利用的小儲存塊。

1.記憶體申請流程圖

小於等於128k的用第二級分配器;

大於128k的用第一級分配器

2. 第一級配置器:

第一級採用malloc、free;

此外,這個配置器提供了當記憶體配置錯誤時的處理函式oom*malloc,這個函式會呼叫*_malloc_alloc_oom_handler()這個錯誤處理函式,去企圖釋放記憶體,然後重新呼叫malloc分配記憶體。如此迴圈,直到分配成功,返回指標(所以再一定程度上提高記憶體分配成功)。

3. 第二級配置器

使用自由鍊錶(free-list)技巧。主動將不論什麼小額區塊的記憶體需求量上調至8的倍數。如需求30,則上調至32。

free-list節點結構

union obj 

有16個free-lists。各自管理大小分別為8、16、24、32、40、48、56、64、72、80、88、96、104、112、120、128 bytes的小額區塊。

釋放記憶體

所以最終記憶體池的思路其實是這樣的:

1. 使用allocate向記憶體池請求size大小的記憶體空間, 如果需要請求的記憶體大小大於128bytes, 直接使用malloc.

2. 如果需要的記憶體大小小於128bytes, allocate根據size找到最適合的自由鍊錶.

a. 如果鍊錶不為空, 返回第乙個node, 煉表頭改為第二個node.

b. 如果鍊錶為空, 使用blockalloc請求分配node.

x. 如果記憶體池中有大於乙個node的空間, 分配竟可能多的node(但是最多20個), 將乙個node返回, 其他的node新增到鍊錶中.

y. 如果記憶體池只有乙個node的空間, 直接返回給使用者.

z. 若果如果連乙個node都沒有, 再次向作業系統請求分配記憶體.

①分配成功, 再次進行b過程

②分配失敗, 迴圈各個自由鍊錶, 尋找空間

i. 找到空間, 再次進行過程b

ii. 找不到空間, 丟擲異常(**中並未給出, 只是給出了注釋)

3. 使用者呼叫deallocate釋放記憶體空間, 如果要求釋放的記憶體空間大於128bytes, 直接呼叫free.

4. 否則按照其大小找到合適的自由鍊錶, 並將其插入.

特點其實是這樣的 :

1. 剛開始初始化記憶體池的時候, 其實記憶體池中並沒有記憶體, 同時所有的自由鍊錶都為空鍊錶.

2. 只有使用者第一次向記憶體池請求記憶體時, 記憶體池會依次執行上述過程的 1->2->b->z來完成記憶體池以及鍊錶的首次填充, 而此時, 其他未使用鍊錶仍然是空的.

3. 所有已經分配的內存在記憶體池中沒有任何記錄, 釋放與否完全靠程式設計師自覺.

4. 釋放記憶體時, 如果大於128bytes, 則直接free, 否則加入相應的自由鍊錶中而不是直接返還給作業系統.

c stl記憶體分配

sgi stl中stl 的記憶體分配不是採用allocator類,而是採用自己寫的類alloc 這個alloc類中主要有四個函式 construct 用於呼叫新建類的建構函式,其實現就是依靠placement new destroy 用於呼叫新建類的析構函式 allocate 用於分配新建類的記憶體...

記憶體池 C 記憶體池

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

記憶體池 執行緒池

1 記憶體池是在真正使用記憶體之前,先申請分配一定數量的 大小相等 一般情況下 的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊不夠再繼續申請新的記憶體。這樣做的乙個顯著優點是,使得記憶體分配效率得到提公升。2 執行緒池是一種多執行緒處理形式,處理過程中將任務新...