STL Allocator記憶體配置器

2021-10-23 08:12:26 字數 3435 閱讀 3349

stl的記憶體配置器考慮到了小型的區塊可能造成記憶體破碎問題,sgi stl 設計了雙層級配置器,第一層配置器直接使用malloc() 和 free().第二層配置器則視情況採用不同的策略:但配置區塊超過 128 bytes時,呼叫第一級配置器。當配置區塊小於 128 bytes時,採用複雜的 memory pool 方式。

class

__malloc_alloc_template

static

void

deallocate

(void

*p, size_t /* n */

)template

<

int inst>

void

* __malloc_alloc_template

::oom_malloc

(void

*p, size_t n)

//如果自己沒有定義oom處理函式,則編譯器毫不客氣的丟擲異常。

(*my_malloc_handler)()

;//執行自定義的oom處理函式

result =

malloc

(n);

//重新分配空間

if(result)

return

(result)

;//如果分配到了,返回指向記憶體的 指標}}

}

通過**可以看出在第一級配置器中是用了原生的配置器malloc來分配記憶體,free來釋放記憶體,當記憶體不足時去呼叫oom_malloc函式去申請記憶體,具體的申請函式的方法需要自己去定義。

維護了16個自由鍊錶(free lists),負責16種小型區塊的次配置能力。記憶體池以malloc()配置而得。如果記憶體不足,則呼叫第一級配置器

如果需求大於128kb,也轉呼叫第一級記憶體配置器。

第二級配置器維護了16個free_lists的結構,每乙個free_lists的結構負責管理與之相關大小的記憶體區塊。

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

free_lists的節點結構如下:

union obj

;

第二級配置器的allocator的實現:
static

void

*allocate

(size_t n)

//尋找 16 個free lists中恰當的乙個

my_free_list = free_list +

freelist_index

(n);

result =

*my_free_list;

if(result ==0)

*my_free_list = result -

> free_list_link;

return

(result);}

;

從**中,可以看出分為三種情況。

第一種,申請空間大於128bytes,則呼叫第一級配置器分配;

第二種,free_list中記憶體區塊不足,需要從記憶體池中申請記憶體區塊。

第三種,從free_list中獲取合適的區塊。

第一種情況就是直接呼叫預設的第一級配置器。

第二種情況是通過refill函式實現,下面會具體展開講述。

第三種情況則是通過鍊錶來實現。

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-zwnbdpv3-1590139655521)(c:\users\andyhkmo\desktop\學習筆記\photo\stl_allocator.png)]

第二級配置器的deallocator的實現:

static

void

deallocate

(void

*p, size_t n)

//尋找對應的位置

my_free_list = free_list +

freelist_index

(n);

//以下兩步將待釋放的塊加到鍊錶上

q -> free_list_link =

*my_free_list;

*my_free_list = q;

}

從**可以看到,施放過程比較簡單,如果大於128bytes,呼叫第一級配置器free介面釋放記憶體。

反之,把該區塊**到鍊錶中。

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-mh9i2wzm-1590139655525)(c:\users\andyhkmo\desktop\學習筆記\photo\stl_allocator1.png)]

refill操作

在剛剛闡述的allocator分配記憶體操作中,當鍊表中不足以分配記憶體時,則需要通過refill操作去向記憶體池申請記憶體。而refill操作主要通過chunk_alloc去實現從記憶體池中取空間給free_list使用。

// 從記憶體池取出空間給free_list使用(第n號)(假定size已經適當調整為8的倍數)

char

*alloc::

chunk_alloc

(size_t size,

int&n_objs)

else

if(bytes_left >= size)

else

// 配置heap空間, 用來補充記憶體池

start_free =

(char*)

malloc

(bytes_to_get);if

(nullptr

== start_free)

} end_free =0;

} heap_size +

= bytes_to_get;

end_free = start_free + bytes_to_get;

return

chunk_alloc

(size, n_objs);}

}

分為以下幾種情況:

記憶體池中恰好有足夠大的空間,則直接返回;

記憶體池中不能完全滿足需求量,但是足夠**乙個以上的區塊,則返回足夠的區塊大小。

記憶體池中乙個區塊都不能夠滿足,

3.1 首先把剩餘的記憶體空間分配到合適的桶中(free_list)

3.2 然後用malloc去申請2倍的需求記憶體大小。

3.3 如果申請成功,則返回需求的記憶體空間大小。

3.4 如果申請不成功,則需要從freelist(大於需求的塊)中檢視,是否有空閒的塊還沒使用,遞迴查詢。

11 2 分配記憶體

這篇主要說一說c語言中幾個分配記憶體的函式 malloc calloc 和free 內容在書12.4章.c語言可以通過庫函式分配和管理記憶體.下面的 都為變數分配了一些記憶體.float f char str this is a string int arr 100 靜態資料在程式載入記憶體時分配記...

Docker tomcat的設定記憶體大小配置方式

通過將docker中tomcat的catalina.sh配置檔案掛載到宿主機中,然後再catalina.sh配置jvm記憶體大小即可。docker run d v server webapps usr local tomcat webapps程式設計客棧 v server catalina.sh u...

15 分配記憶體失敗的考查

void test void 答 malloc後,應判斷 p是否null 這個題目自身有問題,深層次思考 出題人原意,free str 後,用str null杜絕野指標,但是這種寫法過於教科書化,離開這個函式,str都不能使用了,還搞個str null,不需要 在c 中,如果使用new,更不需要,參...