STL的記憶體配置器分配例子

2021-07-24 11:57:36 字數 2296 閱讀 3197

在stl中考慮到小型區塊所可能造成的記憶體破碎問題,sgi stl設計了雙層級配置器,第一級配置器直接使用malloc()和free();第二級配置器則視情況採用不同的策略:當配置區塊超過128bytes時,則視之為足夠大,便呼叫第一級配置器;當配置區塊小於128bytes時,則視之為過小,為了降低額外負擔,便採用複雜的記憶體池的方式來整理,而不再求助於第一級配置器。

內定義了兩個template,乙個是__malloc_alloc_template,這是sgi stl的一級配置器,它的allocate()直接使用malloc()而deallocate()直接使用free(),同時,它模擬c++的set_new_handler()處理記憶體不足的狀況。第二個是__default_alloc_template,它維護了16個free list,每個list上集合著大小分別為8,16,24,...128大小的記憶體塊。記憶體池以malloc()配置而得,如果記憶體不足,轉呼叫第一級配置器,因為那裡設定了記憶體不足的處理程式。如果請求的記憶體塊大小大於128bytes,就轉呼叫第一級配置器。另外定義了兩個alloc,乙個是debug_alloc,每次配置一塊記憶體時,都會配置比需求多8byte的空間以儲存空間大小,通過assert語句來檢查會不會記憶體溢位。另乙個是******_alloc,定義了兩個版本的allocate和deallocate,它們都只是單純的轉呼叫。sgi stl容器全都使用******_alloc介面。free-list的節點巧妙地使用了乙個union結構來管理鍊錶:

cpp**  

union obj  

每次配置器需要向系統要記憶體的時候,都不是按客戶需求向系統申請的,而是一次性向系統要了比需求更多的記憶體,放在記憶體池裡,有乙個free_start和free_end指示剩餘的空間(也就是說記憶體池剩餘的空間都是連續的,因此每次重新向system heap要空間的時候,都會把原先記憶體池裡沒用完的空間分配給合適的free list。)當free-list中沒有可用區塊了的時候,會首先從記憶體池裡要記憶體,同樣,也不是以按客戶需求要多少塊的,而是一次可能會要上20塊,如果記憶體池內空間允許的話,可能會得到20個特定大小的記憶體,如果記憶體池給不了那麼多,那麼就只好盡力給出;如果連乙個都給不出,那麼就要開始向系統即system heap要空間了。換算的標準是bytes_to_get=2*total_bytes+round_up(heap_size>>4)。這個時候使用的是malloc,如果沒成功,就嘗試著從大塊一點的freelist那裡要乙個來還給記憶體池,如果還是不行,那麼會呼叫第一級空間配置器的malloc::allocate,看看out-of-memory機制能做點什麼不。

總結起來整個過程大概是這樣的,假設我們向系統要x大小的記憶體,

(1)x大於128byte,用第一級配置器直接向系統malloc,至於不成功的處理,過程仿照new,通過set_new_handler來處理,直到成功返回相應大小的記憶體或者是丟擲異常或者是乾脆結束執行;

(2)x小於128byte,用第二級配置器向記憶體池相應的free_list要記憶體,如果該freelist上面沒有空閒塊了,

(2.1)從記憶體池裡面要記憶體,預設是獲得20個節點,如果記憶體池中剩餘的空間不能完全滿足需求量,但足夠**乙個(含)以上的區塊,則應盡力滿足需求。

(2.2)如果乙個都不能夠滿足的話,則從系統的heap裡面要記憶體給到記憶體池,換算的標準是bytes_to_get=2*total_bytes+round_up(heap_size>>4),申請的大小為需求量的兩倍加上乙個附加值,如果記憶體池中還有剩餘的記憶體,則將殘餘零頭分配給適當的free list,這時使用的是系統的malloc,如果要不到:

(2.3)從比較大的freelist那裡要記憶體到記憶體池,如果還是要不到:

(2.4)從系統的heap裡面要記憶體給到記憶體池,換算標準跟2.2一樣,但是這時候使用的是第一級配置器的allocate,主要是看看能不能通過out_of_memory機制得到一點記憶體。所以,freelist總是從記憶體池裡要記憶體的,而記憶體池可能從freelist也可能從系統heap那裡要記憶體。

sgi stl的alloc的主要開銷就在於管理這些小記憶體,管理這些小記憶體的主要開銷就在於,每次freelist上的記憶體塊用完了,需要重新要空間,然後建立起這個list來。freelist上的記憶體,會一直保留著直到程式退出才還給系統。但這不會產生記憶體洩漏,一來是管理的都是小記憶體,二來是,占用的記憶體只會是整個程式執行過程中小記憶體佔用量最大的那一刻所占用的記憶體。

STL配置器的記憶體分配策略

stl的幾個組成部分 1.容器 各種資料結構 2.演算法 各種常用演算法 3.迭代器 容器與演算法之間的聯合器,泛型指標 4.仿函式 協助演算法完成不同的策略的變化?5.介面卡 修飾或套接仿函式?6.配置器 分配空間管理 配置器的記憶體空間管理策略 一級配置器 對於大於128b的空間,使用一級配置器...

STL記憶體分配

stl記憶體分配 由於小型的記憶體區塊會因此記憶體分配碎片,sgi stl設計中使用了雙層級配置器,第一級配置器直接使用malloc 和free 申請記憶體大於128位元組時呼叫 第二級配置器採用記憶體池的方式來管理。stl記憶體分配器在檔案中實現,malloc alloc template和 de...

STL記憶體配置器

一 stl記憶體配置器的總體設計結構 1.兩級記憶體配置器 sgi stl中設計了兩級的記憶體配置器,主要用於不同大小的記憶體分配需求,當需要分配的記憶體大小大於128bytes時,使用第一級配置器,否則使用第二級配置器 對於小塊的記憶體的分配使用第二級配置器使用分配與釋放記憶體塊的效率更高,時間複...