我們都知道stl裡有很多容器,如vector,stack,queue等等,每個容器都是通過配置器來獲取儲存空間的,現在來總結下配置器原理
當我們建立乙個物件時常用方式是new,銷毀乙個物件用delete
t* a = new t;
delete a;
對於new 其實是先呼叫為其配置記憶體,再呼叫相應的建構函式,對於delete是先呼叫析構函式再釋放記憶體
記憶體配置操作是有allocate來完成,構造由construct完成
主要來看空間的配置,配置器定義位於中,其中負責記憶體空間的配置和析構的主要在下面標頭檔案中
#include
sgi兩層配置器
sgi設定了兩級配置器,對於大於128位元組的申請用第一級配置器,小於則用第二級配置器,他們拿到記憶體空間的途徑不同,主要思想是大塊記憶體就直接malloc從記憶體裡申請,小塊的就先從記憶體池裡申請,這樣可以避免產生很多的外碎片。
一級配置器
直接呼叫malloc/free來申請空間,並有異常狀態處理機制,即當記憶體配置需求無法被滿足時會呼叫使用者自己定義的乙個指定函式,來看原始碼
templateclass __mallocalloctemplate //一級空間配置器
static void deallocate(void* p, size_t n)
static void* reallocate(void* p, size_t oldsz, size_t newsz)
static oom_handler setmallochandler(oom_handler f)
};templatevoid (*__mallocalloctemplate::oom_handler)() = null;
templatevoid* __mallocalloctemplate::oom_malloc(size_t n)
}templatevoid* __mallocalloctemplate::oom_realloc(void* p, size_t newsz)
}typedef __mallocalloctemplate<0> mallocalloc;
可以看到allocate和realloc都是在呼叫malloc和realloc不成功後,改呼叫oom_malloc()和oom_realloc()
二級配置器
二級配置器管理了乙個記憶體池並維護了乙個自由鍊錶,自由鍊錶通過有16個節點。首先配置器會主動將任何小額區塊的記憶體需求量上調至8的倍數,然後檢查對應的free list,如果free-list中有可用的區塊,就直接拿來,如果沒有,就準備為對應的free-list 重新填充空間
static void* allocate(size_t n)
//...
}
新的空間將取自記憶體池,預設取20個新節點,如果記憶體池不足(還足以乙個以上的節點),就返回的相應的節點數
static void* refill(size_t n)
cur->freelistlink = null;
return ret;
}
如果當記憶體池中連乙個節點大小都不夠時,就申請新的記憶體池,如果申請記憶體池成功就把原來記憶體池中剩下的空間分配給適當的free-list,如果找不到就呼叫第一級配置器,總的概括策略如下
將n位元組擴充套件到8的倍數,找自由鍊錶,有則分配,沒有則向記憶體池申請20×n的記憶體塊
若記憶體池小於20x n,但是比一塊大小n要大,那麼此時將記憶體最大可分配的塊數給自由鍊錶
如果整個記憶體池空間都不夠了,就先將記憶體池殘餘的零頭給掛在自由鍊錶上,然後向系統heap申請空間,申請成功則返回,申請失敗則到自己的自由鍊錶中看看還有沒有可用區塊返回,如果連自由鍊錶都沒了最後會呼叫一級配置器
小結:可以看到stl記憶體分配器是基於空閒鍊錶的最佳分配策略,對小記憶體申請進行了優化,可以避免記憶體碎片產生同時最大化記憶體利用率
深入理解Python裝飾器
主要內容 l local 函式內部作用域 e enclosing 函式內部與內嵌函式之間 g global 全域性作用域 b build in 內建作用域 closure 內部函式中對enclosing作用域的變數進行引用 函式的實質與屬性 函式是乙個物件 函式執行完成後內部變數 函式屬性 函式返回...
深入理解C語言 深入理解指標
關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...
mysql 索引深入理解 深入理解MySql的索引
為什麼索引能提高查詢速度 先從 mysql的基本儲存結構說起 mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶每個資料頁中的記錄又可以組成乙個單向鍊錶 每個資料頁都會為儲存在它裡邊兒的記錄生成乙個頁目錄,在通過主鍵查詢某條記錄的時候可以在頁目錄中使用二分法快速定位到對應...