STL原始碼剖析 記憶體池的實現

2021-09-13 12:18:39 字數 2294 閱讀 1315

2023年3月15日-3月23日,大概花了8天的時間,終於將sgi stl版本實現的記憶體池看懂了。不過記憶體池這個知識點大概在2023年8月份的時候就已經接觸了,今天終於弄懂了,如卸心中之塊壘!在此**的一些點,可能非常表面,如果需要深入了解,建議直接閱讀《stl原始碼剖析·侯捷》相應章節。

記憶體池只是使用兩根指標 start_free 和 end_free 標記其範圍的一段連續的堆空間而已,不負責對記憶體的分配與**。因為乙個記憶體池沒有辦法實現。記憶體分配與**的具體工作交給乙個 陣列+鍊錶 的結構去處理。我的本意是藉著記憶體池這個切入點將 stl 中的空間配置器進行乙個總結。

記憶體池的好處:1)時間效率高,如果每次需要動態申請記憶體都直接向system heap 索取,那麼時間開銷比較大;2)空間利用率高,每個從system heap 取得的區塊都會包含記錄本區塊大小的頭部資訊,這也是沒辦法的事情。有了頭部資訊這個技巧,程式設計師釋放空間的時候只需要告知系統一根指標即可,系統會自動根據頭部讀取到的數目進行空間的釋放。如果不帶頭部資訊,那麼釋放記憶體區塊需要提供 指標+位元組數,這對程式設計師來說負擔過重,程式設計師得記下每次申請的空間的對應大小。如果維護在記憶體池中,就沒有頭部資訊,空間利用率顯著提高。在《stl原始碼剖析·侯捷》一書中關於頭部資訊使用了乙個形象的比喻——「稅」。

什麼樣的陣列?什麼樣的鍊錶?

每個陣列元素代表一條鍊錶,分別管理 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128 byte的小額區塊。 大於128byte,直接使用malloc進行索取。

在c++中沒有介面,但是可以用乙個純虛類來模擬介面。此處談及的介面,不是程式設計方面的介面;而是軟體設計方面的介面。介面定義了類的外觀,最重要的乙個設計語義就是封裝變化——「隔離變化」。

在 stl 規範中,必要介面有哪些呢?

allocator::value_type

allocator::pointer

allocator::const_pointer

allocator::reference

allocator::const_reference

allocator::size_type

allocator::difference_type

allocator::rebind

allocator::allocator() //default ctor

allocator::allocator(const allocator&) //copy ctor

tmeplateallocator::allocator(const allocator&) //泛化的 copy ctor

allocator::~allocator()

pointer allocator::address(reference x) const //返回某個物件的位址

const_pointer allocator::address(const_reference x) const //返回某個const物件的位址

pointer allocator::allocate(size_type n, const void* = 0) //配置空間

void allocator::deallocate(pointer p, size_type n) //歸回原先配置的空間

size_type allocator::max_size() const //返回可成功配置的最大量

void allocator::construct(pointer p, const t &x) //replacement new

void allocator::destroy(pointer p) //析構

介面設計之初就該考慮到方方面面的情況,一旦設計好了就不應該輕易改變。 

static void * allocate(size_t n)

//否則,向自由鍊錶申請,若自由鍊錶不足,直接到記憶體池申請。

my_free_list = free_list + freelist_index(n);

result = *my_free_list;

if(result == 0)

*my_free_list = result->free_list_link;

return (result);

}

記憶體池負責提供空間,陣列+鍊錶結構負責對空間進行管理(包含分配和**)。三者相互協作,達到了效率上的最大化。

STL原始碼剖析

這兩天略讀完了 stl原始碼剖析 之所以是略讀,就是只看大體,不講具現 這個詞在 深度探析c 物件模型 中比較多 已經看過好幾本c 的書了,感覺c 本身設計的博大精深,而c 編譯器就更是乙個神奇的東西,換句話說,你永遠不知道c 編譯器揹著你做了哪些出乎你意料的事 不扯遠了 我主要是想看stl容器的具...

STL原始碼剖析

這兩天略讀完了 stl原始碼剖析 之所以是略讀,就是只看大體,不講具現 這個詞在 深度探析c 物件模型 中比較多 已經看過好幾本c 的書了,感覺c 本身設計的博大精深,而c 編譯器就更是乙個神奇的東西,換句話說,你永遠不知道c 編譯器揹著你做了哪些出乎你意料的事 不扯遠了 我主要是想看stl容器的具...

STL原始碼剖析

花了兩天時間略讀了一下 stl原始碼分析 看了個大體,對於細節並沒有深究。之所以想翻翻這本書,主要是想看看stl中的特性 介面卡的具體實現。看完之後收穫還是蠻大的,模板的各種組合讓我眼前一亮,下面大概總結一些內容。1.記憶體分配 sgi記憶體分配採用兩級實現,對於大記憶體塊的申請 大於128k 由第...