一般而言,我們習慣的 c++ 記憶體配置操作和釋放操作是這樣的:
class foo{};
foo *pf = new foo;
delete pf;
我們看其中第二行和第三行,雖然都是只有一句,當是都完成了兩個動作。但你 new 乙個物件的時候兩個動作是:先呼叫::operator new 分配乙個物件大小的記憶體,然後在這個記憶體上呼叫foo::foo()構造物件。同樣,當你 delete 乙個物件的時候兩個動作是:先呼叫foo::~foo() 析構掉物件,再呼叫::operator delete將物件所處的記憶體釋放。為了精密分工,stl 將allocator決定將這兩個階段分開。分別用 4 個函式來實現:1.記憶體的配置:alloc::allocate();2.物件的構造:::construct();3.物件的析構:::destroy();
4.記憶體的釋放:alloc::deallocate();
template inline void construct(t1* p, const t2& value)
其中construct使用了placement new在sgi版本的stl中,空間的配置釋放都由< stl_alloc.h > 負責。它的設計思想如下:
考慮到小型區塊可能造成記憶體破碎問題(即形成記憶體碎片),sgi stl 設計了雙層級配置器。第一層配置器直接使用malloc() 和 free().第二層配置器則視情況採用不同的策略:但配置區塊超過 128 bytes時,呼叫第一級配置器。當配置區塊小於 128 bytes時,採用複雜的 memory pool 方式。
如上圖所示,自由鍊錶是乙個指標陣列,有點類似與hash桶,它的陣列大小為16,每個陣列元素代表所掛的區塊大小,比如free _ list[0]代表下面掛的是8bytes的區塊,free _ list[1]代表下面掛的是16bytes的區塊…….依次類推,直到free _ list[15]代表下面掛的是128bytes的區塊
同時我們還有乙個被稱為記憶體池地方,以start _ free和 end _ free記錄其大小,用於儲存未被掛在自由鍊錶的區塊,它和自由鍊錶構成了夥伴系統。
如果使用者需要是一塊n位元組的區塊,且n <= 128(呼叫第二級配置器),此時refill填充是這樣的:(需要注意的是:系統會自動將n位元組擴充套件到8的倍數也就是roundup(n),再將roundup(n)傳給refill)。使用者需要n塊,且自由鍊錶中沒有,因此系統會向記憶體池申請nobjs * n大小的記憶體塊,預設nobjs=20
參考資料:
STL相關知識
c 的標準模板庫 standard template library,簡稱stl 是乙個容器和演算法的類庫。容器往往包含同一型別的資料。stl中比較常用的容器是vector,set和map等。vectore 乙個vector類似於乙個動態的一維陣列,vector中可以存在重複的元素!1 宣告 1 v...
XMPP 相關知識整理
xmpp the extensible messaging and presence protocol 中文全稱 可擴充套件通訊和表示協議 簡介 可擴充套件通訊和表示協議 xmpp 可用於服務類實時通訊 表示和需求響應服務中的xml資料元流式傳輸。xmpp以jabber協議為基礎,而jabber是即...
patch,diff相關知識整理
diff 命令列選項 原始檔案 新檔案 幾個常用的選項說明 diff的內容預設輸出到stdout上,所以需要把它重定向到乙個檔案中才能儲存,如下 diff un test0 test1 test1.patch如果是資料夾就加個r 常用 rnu就行 patch 命令列選項 待打補丁的檔案或文件 補丁檔...