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,更不需要,參...