一、空間的配置與釋放,std::alloc
物件構造前的空間配置和物件析構後的空間釋放,由負責,sgi對此的設計哲學如下:
1. 向 system heap 要求空間。
2. 考慮多執行緒(multi-threads)狀態。
3. 考慮記憶體不足時的應變措施。
4. 考慮過多「小型區塊」可能造成的記憶體碎片(fragment)問題。
考慮到小型區塊所可能造成的記憶體破碎問題,sgi設計了雙層級配置器,第一級配置器直接使用 malloc() 和 free() ,第二級配置器則視情況採用不同的策略:當配置區塊超過 128 bytes時,視之為「足夠大」,便呼叫第一級配置器;當配置區塊小於 128 bytes時,視之為「過小」,為了降低額外負擔,便採用複雜的 memory pool 整理方式,而不再求助於第一級配置器。
在sgi的整個設計究竟只開放第一級配置器,或是同時開放第二級配置器,取決於 __use_malloc 是否被定義。
#ifdef __use_malloc
...typedef __malloc_alloc_template<0> malloc_alloc;
typedef malloc_alloc alloc; // 令 alloc 為第一級配置器
#else
...// 令 alloc 為第二級配置器
typedef __default_alloc_template<__node_allocator_threads, 0> alloc;
#endif /* ! __use_malloc */
其中 __malloc_alloc_template 就是第一級配置器,__default_alloc_template 就是第二級配置器。sgi stl並未定義 __use_malloc,所以sgi使用第二級配置器。
sgi 還為 alloc 包裝了乙個介面如下,使配置器的介面能夠符合 stl 規格:
templateclass ******_alloc
static t *allocate(void)
static void deallocate(t *p, size_t n)
static void deallocate(t *p)
};
其內部四個成員函式其實都是單純的轉呼叫,呼叫傳遞給配置器的成員函式。sgi stl容器全部使用這個 ******_alloc 介面。
二、第一級配置器 __malloc_alloc_template 剖析
// 注意,無"template型別引數"。至於"非型別引數"inst,則完全沒派上用場
template class __malloc_alloc_template
static void deallocate(void *p, size_t /* n */)
static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)
// 以下**c++的 set_new_handler()。換句話說,可以通過它
// 指定你自己的 out-of-memory handler
static void (* set_malloc_handler(void (*f)()))()
};// malloc_alloc out-of-memory handling
#ifndef __stl_static_template_member_bug
// 初值為 0。有待客端設定
template void (* __malloc_alloc_template::__malloc_alloc_oom_handler)() = 0;
#endif
template void * __malloc_alloc_template::oom_malloc(size_t n)
(*my_malloc_handler)(); // 呼叫處理例程,企圖釋放記憶體
result = malloc(n); // 再次嘗試配置記憶體
if (result) return(result);
}}template void * __malloc_alloc_template::oom_realloc(void *p, size_t n)
(*my_malloc_handler)(); // 呼叫處理例程,企圖釋放記憶體
result = realloc(p, n); // 再次嘗試配置記憶體
if (result) return(result);
}}// 注意,以下直接將引數 inst 指定為 0
typedef __malloc_alloc_template<0> malloc_alloc;
第一級配置器以 malloc(),free(),realloc()等 c 函式執行實際的記憶體配置、釋放、重配置操作,並實現出類似 c++ new-handler 的機制。(所謂 c++ new handler 機制是,你可以要求系統在記憶體配置需求無法被滿足時,呼叫乙個你所指定的函式。換句話說,一旦 ::operator new 無法完成任務,在丟出 std::bad_alloc 異常狀態之前,會先呼叫由客端指定的處理例程。)
設計「記憶體不足處理例程」是客端的責任,設定「記憶體不足處理例程」也是客端的責任。
STL原始碼剖析 空間配置器
看過stl空間配置器的原始碼,總結一下 1 stl空間配置器 主要分三個檔案實現,stl construct.h 這裡定義了全域性函式construct 和destroy 負責物件的構造和析構。stl alloc.h檔案中定義了 一 二兩級配置器,彼此合作,配置器名為alloc.stl uninit...
STL原始碼剖析 空間配置器
allocator是空間配置器而不是記憶體配置器,空間不一定是記憶體,也可以是磁碟或其他輔助儲存介質。但sgi stl提供的配置器配置的物件是記憶體。sgi標準的空間配置器,std alloctor sgi定義了乙個符合部分標準,名為alloctor的配置器,效率不高,只把c 的 operator ...
STL原始碼剖析 空間配置器
由於物件的建立分為分配記憶體和呼叫建構函式兩部分,stl allocator使用alloc allocate 來分配記憶體,construct 構造物件。construct 函式只有乙個泛化的版本,destroy 函式有乙個泛化的針對迭代器的版本,destroy aux 根據是否需要呼叫析構函式進行...