STL學習筆記——空間配置器
1.基本元件
容器(Container)、演算法(Algorithm)、迭代器(Iterator)、仿函式(Functor)、容器介面卡(Adapter)、空間配置器(Allocator)
2.元件關係容器通過空間配置器獲取資料儲存空間;演算法通過迭代器存取容器內容;
仿函式幫助演算法完成不同策略的選擇;容器介面卡可以修飾或套接仿函式;
二、空間配置器
#include<memory>//標頭檔案
#include<stl_alloc.h>//負責記憶體空間的配置與釋放
#include<stl_construct.h>
1.物件的構造與析構
1)由定義的全域性函式construct()和destory()來進行;
2)其中destory中用到了Traits技術,通過判斷類的類別進行不同的析構操作,
類的解構函式為trivial(無用的)則無視、類的解構函式為no-trivial(需要釋放記憶體等必要操作)則執行,
通過這種方式可以提高效率。
2.記憶體空間的申請與釋放採用雙層配置器
1)一級配置器(申請記憶體大於128byte)
a. allocate():直接使用malloc從系統的heap空間申請記憶體,若記憶體不足呼叫oom_malloc()
b. deallocate():直接使用free(p)釋放記憶體;
c. oom_**alloc():(out of memory)實現了類似C++ new-handler機制,即在記憶體分配不夠的情況下,先執行客戶指定的處理
例程(不斷嘗試釋放記憶體並重新配置),若記憶體失敗則丟出bad_alloc異常。
注意:設計和設定記憶體不足處理例程是客戶端的責任。
2)二級配置器(申請記憶體小於等於128byte)
a. allocate(): 首先判斷申請的記憶體大小,超過128byte呼叫第一級配置器,否則啟動第二級配置器
記憶體池中取記憶體交付給使用者。這個記憶體池由16個負責不同大小(8-128byte)區塊的自由連結串列組成類似於
hash桶結構,配置器會根據申請的記憶體大小(round up成8的倍數)從對應的自由連結串列塊取表頭給
客戶。表頭儲存了對應記憶體池中的地址。如果要申請的大小在空閒連結串列上沒有,就從記憶體池中獲取 (chunk_alloc),若記憶體池空間不夠就通過malloc擴充記憶體池空間(大小為需求量的兩倍還有隨著申請次數
增加而愈來愈大的附加量)。若從系統heap空間申請記憶體失敗,就先從自由連結串列中尋找尚未使用且區塊夠大的內 存,若沒有就呼叫第一級配置器(通過oom能否獲得記憶體)。
b. deallocate():首先判斷釋放的記憶體大小,超過128byte呼叫第一級配置器,否則啟動第二級配置器根據記憶體大小找到對應的自由連結串列塊,將其加入表頭。
3)採用兩級配置器的優點:小記憶體的快速分配與釋放;避免了記憶體碎片的產生;儘可能最大化記憶體利用率;
3.記憶體基本處理工具
1)uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result):
將迭代器first到last內的資料copy到result。
2)uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x):
用x初始化迭代器從first到last的範圍。
3)uninitialized_fill_n(ForwardIterator first, Size n ,const T& x):
為指定範圍內的所有元素設定相同的初值。