談?wù)効臻g配置器(allocator)

空間配置器是STL用來分配和管理空間的類型凌受;STL allocator將對象的構(gòu)造齿桃、析構(gòu)與內(nèi)存的配置和釋放分開 惠窄。對象的構(gòu)造和析構(gòu)由construct(placement new在指定空間創(chuàng)建對象) 和destroy負(fù)責(zé)(全局函數(shù))谅辣。內(nèi)存的配置和釋放由allocate和deallocate負(fù)責(zé)懦窘。

SGI STL的兩級(jí)空間配置器

SGI STL 為了避免小型區(qū)塊的內(nèi)存碎片(fragment)問題,SGI設(shè)計(jì)了兩級(jí)配置器

當(dāng)配置區(qū)塊大于128字節(jié)時(shí)前翎,調(diào)用第一級(jí)配置器。小于128字節(jié)時(shí)調(diào)用第二級(jí)配置器畅涂。

第一級(jí)配置器(alloc)的allocate()和deallocate()函數(shù)只是簡單調(diào)用malloc()和free()函數(shù)港华;

如果出現(xiàn)了out_of_memory錯(cuò)誤,就不斷調(diào)用__malloc_alloc_oom_handler()錯(cuò)誤處理函數(shù)午衰,去嘗試釋放內(nèi)存立宜,然后重新調(diào)用malloc分配。不斷循環(huán)臊岸,直到分配成功橙数。(如果沒設(shè)置這個(gè)處理函數(shù),就拋出bad_alloc異常)

第二級(jí)配置器為了降低額外開銷(overhead)扇单,采用內(nèi)存池(memory pool)管理內(nèi)存分配商模;具體使用的內(nèi)存塊從free-list(自由鏈表)中提取出。

具體流程為:

1.當(dāng)需要申請的內(nèi)存大小N 大于128bytes時(shí)蜘澜,直接使用第一級(jí)配置器施流,使用malloc分配

2.小于等于128bytes時(shí),使用內(nèi)存池管理鄙信。內(nèi)存池管理步驟為:

a. 首先查看是否有可用的free-list瞪醋,如果有就直接使用。沒有的話装诡,將所需區(qū)塊大小上調(diào)至8的倍數(shù)银受,調(diào)用 refill()為free list重新分配空間践盼。

b. 新的空間將取自內(nèi)存池(經(jīng)由chunk_alloc()完成),如果內(nèi)存池不夠用宾巍,從堆空間(malloc配置空間) 拿來補(bǔ)充內(nèi)存池咕幻。如果堆空間也不夠了,就調(diào)用第一級(jí)配置器來補(bǔ)充內(nèi)存池顶霞。因?yàn)榈谝患?jí)配置器有out-of- memory處理機(jī)制肄程,看看它能不能釋放其它內(nèi)存然后拿來此處使用(如果可以就成功,否則bad_alloc異常)选浑。

這里要注意一點(diǎn)蓝厌,最初內(nèi)存池和free list都為空。

內(nèi)存池如何refill()鏈表

當(dāng)free list中無可用區(qū)塊古徒,將向內(nèi)存池申請空間拓提。當(dāng)內(nèi)存池空間充足時(shí),新的空間將缺省獲得20個(gè)新的區(qū)塊大小N(所需內(nèi)存空間上調(diào)8的倍數(shù))隧膘。當(dāng)內(nèi)存池空間不滿足需求量代态,先盡可能分配出大小為N的內(nèi)存塊。如果內(nèi)存池剩余空間小于N舀寓,先將內(nèi)存池的殘余分給free list,然后向堆空間申請內(nèi)存胆数。

內(nèi)存池以及free list一次配置這么大的空間,是為了不頻繁申請內(nèi)存互墓,減小不必要的開銷。

free list

free-list:是有16個(gè)大小分別為8蒋搜,16一直遞增到128字節(jié)的內(nèi)存塊構(gòu)成的鏈表篡撵。因此第二級(jí)配置器最大只能分配128字節(jié)。

free-list相比鏈表豆挽,如何實(shí)現(xiàn)減少額外負(fù)擔(dān)育谬?

普通鏈表不僅要有指針指向?qū)嶋H區(qū)塊,還要維護(hù)指向下一個(gè)節(jié)點(diǎn)的指針帮哈,所以會(huì)有額外的負(fù)擔(dān)膛檀。

free-list采用的是聯(lián)合體(union,算是一種數(shù)據(jù)類型)娘侍,聯(lián)合體數(shù)據(jù)成員共享一塊內(nèi)存咖刃。兩個(gè)數(shù)據(jù)成員,一個(gè)是指向下一個(gè)節(jié)點(diǎn)的指針憾筏,另外一個(gè)是指向?qū)嶋H區(qū)塊的指針嚎杨。

這兩個(gè)數(shù)據(jù)成員在任何時(shí)刻只有一個(gè)有值,對應(yīng)于分配的兩種情況——分配和不分配氧腰。不分配時(shí)枫浙,使用的是指向下一節(jié)點(diǎn)的這一數(shù)據(jù)成員刨肃。分配時(shí)(區(qū)塊拔出,不用指向下一節(jié)點(diǎn))箩帚,則使用的指向?qū)嶋H區(qū)塊的這一數(shù)據(jù)成員真友。

內(nèi)存池:是一種內(nèi)存分配方式,頻繁使用new紧帕、malloc會(huì)造成大量內(nèi)存碎片锻狗。并且頻繁分配和回收內(nèi)存會(huì)降低性能。內(nèi)存池一次申請一定數(shù)量的內(nèi)存塊留作備用焕参,因此不用頻繁去申請新的資源轻纪。

聯(lián)合體(union)

聯(lián)合體(union)是一種節(jié)省空間的類,其特性是一個(gè)union可以有多個(gè)數(shù)據(jù)成員叠纷,但是在任意時(shí)刻只能有一個(gè)數(shù)據(jù)成員可以有值刻帚。聯(lián)合體的大小為最大數(shù)據(jù)成員的大小,本質(zhì)是數(shù)據(jù)成員共享內(nèi)存涩嚣,從而實(shí)現(xiàn)節(jié)省空間的目的崇众。

聯(lián)合體與類的區(qū)別
  • 聯(lián)合體的數(shù)據(jù)成員默認(rèn)為public,與struct相同航厚,而class默認(rèn)為private顷歌。

  • 聯(lián)合體不能作為基類,不能繼承幔睬,因此數(shù)據(jù)成員也不能有虛函數(shù)

  • union的數(shù)據(jù)成員不能有引用類型(引用必須初始化且不能修改綁定)

  • C++11允許union含有定義了構(gòu)造函數(shù)或拷貝控制成員的類類型成員

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末眯漩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子麻顶,更是在濱河造成了極大的恐慌赦抖,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辅肾,死亡現(xiàn)場離奇詭異队萤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)矫钓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門要尔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人新娜,你說我怎么就攤上這事赵辕。” “怎么了杯活?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵匆帚,是天一觀的道長。 經(jīng)常有香客問我旁钧,道長吸重,這世上最難降的妖魔是什么互拾? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮嚎幸,結(jié)果婚禮上颜矿,老公的妹妹穿的比我還像新娘。我一直安慰自己嫉晶,他們只是感情好骑疆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著替废,像睡著了一般箍铭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上椎镣,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天诈火,我揣著相機(jī)與錄音,去河邊找鬼状答。 笑死冷守,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惊科。 我是一名探鬼主播拍摇,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馆截!你這毒婦竟也來了充活?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤孙咪,失蹤者是張志新(化名)和其女友劉穎堪唐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翎蹈,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年男公,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荤堪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡枢赔,死狀恐怖澄阳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踏拜,我是刑警寧澤碎赢,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站速梗,受9級(jí)特大地震影響肮塞,放射性物質(zhì)發(fā)生泄漏襟齿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一枕赵、第九天 我趴在偏房一處隱蔽的房頂上張望猜欺。 院中可真熱鬧,春花似錦拷窜、人聲如沸开皿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赋荆。三九已至,卻和暖如春懊昨,著一層夾襖步出監(jiān)牢的瞬間窄潭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工疚颊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狈孔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓材义,卻偏偏與公主長得像均抽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子其掂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容