国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 操作系統(tǒng) > 正文

分配內(nèi)存時如何減少內(nèi)存碎片

2024-06-28 13:23:58
字體:
供稿:網(wǎng)友
分配內(nèi)存時如何減少內(nèi)存碎片

  感覺面試的時候經(jīng)常會被問到這個問題,然后我也學(xué)習(xí)了一下Memcached的slab機制,發(fā)現(xiàn)很多服務(wù)器都是使用這種機制來分配內(nèi)存,所以決定學(xué)習(xí)一下。

  首先,先對內(nèi)存分配中的伙伴系統(tǒng)有初步的了解:

  在編程和使用的服務(wù)器軟件中,經(jīng)常需要分配一組連續(xù)的頁框,而頻繁地申請和釋放不同大小的連續(xù)頁框,必然導(dǎo)致在已分配頁框的內(nèi)存塊中分散了許多小塊的空閑頁框。這樣,即使這些頁框是空閑的,但要分配一個大塊的連續(xù)頁框就可能無法滿足。  而linux采用了伙伴系統(tǒng)來解決上述難題。把所有的空閑頁框分組為11個塊鏈表,每個塊鏈表分別包含大小為1,2,4,8,16,32,64,128,256,512和1024個連續(xù)頁框的頁框塊。最大可以申請1024個連續(xù)頁框,對應(yīng)4MB大小的連續(xù)內(nèi)存。每個頁框塊的第一個頁框的物理地址是該塊大小的整數(shù)倍。例如,大小為16個頁框的塊,其起始地址是16×212的倍數(shù)。假設(shè)要申請一個256個頁框的塊,先從256個頁框的鏈表中查找空閑塊,如果沒有,就去512個頁框的鏈表中找,找到了則將頁框塊分為2個256個頁框的塊,一個分配給應(yīng)用,另外一個移到256個頁框的鏈表中。如果512個頁框的鏈表中仍沒有空閑塊,繼續(xù)向1024個頁框的鏈表查找,如果仍然沒有,則返回錯誤。頁框塊在釋放時,內(nèi)核會主動將兩個互為伙伴的頁框塊合并為一個較大的頁框塊,成功后會試圖尋找伙伴并合并為更大的內(nèi)存塊,直至塊的大小超過上限或者沒有伙伴為止。互為伙伴的兩個內(nèi)存塊必須符合以下條件:  1、兩個塊具有相同的大小;  2、兩個塊的物理地址連續(xù);  3、第一個快的物理地址是兩個塊大小的整數(shù)倍。  slab分配機制則是對伙伴算法的改進(jìn),slab(Slab Allocation)的設(shè)計理念是基于對象緩沖的,基本想法是避免重復(fù)大量的初始化和清理操作。slab主要可以用于頻繁非配釋放的內(nèi)存對象。替代malloc/free  改進(jìn)的地方在于:

  它對內(nèi)存區(qū)的處理并不需要進(jìn)行初始化或回收。出于效率的考慮,Linux并不調(diào)用對象的構(gòu)造或析構(gòu)函數(shù),而是把指向這兩個函數(shù)的指針都置為空。Linux中引入Slab的主要目的是為了減少對伙伴算法的調(diào)用次數(shù)。

實際上,內(nèi)核經(jīng)常反復(fù)使用某一內(nèi)存區(qū)。例如,只要內(nèi)核創(chuàng)建一個新的進(jìn)程,就要為該進(jìn)程相關(guān)的數(shù)據(jù)結(jié)構(gòu)(task_struct、打開文件對象等)分配內(nèi)存區(qū)。當(dāng)進(jìn)程結(jié)束時,收回這些內(nèi)存區(qū)。因為進(jìn)程的創(chuàng)建和撤銷非常頻繁,因此,Linux的早期版本把大量的時間花費在反復(fù)分配或回收這些內(nèi)存區(qū)上。從Linux2.2開始,把那些頻繁使用的頁面保存在高速緩存中并重新使用。可以根據(jù)對內(nèi)存區(qū)的使用頻率來對它分類。對于預(yù)期頻繁使用的內(nèi)存區(qū),可以創(chuàng)建一組特定大小的專用緩沖區(qū)進(jìn)行處理,以避免內(nèi)碎片的產(chǎn)生。對于較少使用的內(nèi)存區(qū),可以創(chuàng)建一組通用緩沖區(qū)(如Linux2.0中所使用的2的冪次方)來處理,即使這種處理模式產(chǎn)生碎片,也對整個系統(tǒng)的性能影響不大。

硬件高速緩存的使用,又為盡量減少對伙伴算法的調(diào)用提供了另一個理由,因為對伙伴算法的每次調(diào)用都會“弄臟”硬件高速緩存,因此,這就增加了對內(nèi)存的平均訪問次數(shù)。

Slab分配模式把對象分組放進(jìn)緩沖區(qū)

    對于小對象, 就把Slab的描述結(jié)構(gòu)slab_t放在該Slab中;對于大對象,則把Slab結(jié)構(gòu)游離出來,集中存放。關(guān)于Slab中的著色區(qū)再給予具體描述: 每個Slab的首部都有一個小小的區(qū)域是不用的,稱為“著色區(qū)(coloring area)”。著色區(qū)的大小使Slab中的每個對象的起始地址都按高速緩存中的”緩存行(cache line)”大小進(jìn)行對齊(80386的一級高速緩存行大小為16字節(jié),Pentium為32字節(jié))。因為Slab是由1個頁面或多個頁面(最多為32)組成,因此,每個Slab都是從一個頁面邊界開始的,它自然按高速緩存的緩沖行對齊。但是,Slab中的對象大小不確定,設(shè)置著色區(qū)的目的就是將Slab中第一個對象的起始地址往后推到與緩沖行對齊的位置。因為一個緩沖區(qū)中有多個Slab,因此,應(yīng)該把每個緩沖區(qū)中的各個Slab著色區(qū)的大小盡量安排成不同的大小,這樣可以使得在不同的Slab中,處于同一相對位置的對象,讓它們在高速緩存中的起始地址相互錯開,這樣就可以改善高速緩存的存取效率。 每個Slab上最后一個對象以后也有個小小的廢料區(qū)是不用的,這是對著色區(qū)大小的補償,其大小取決于著色區(qū)的大小,以及Slab與其每個對象的相對大小。但該區(qū)域與著色區(qū)的總和對于同一種對象的各個Slab是個常數(shù)。 每個對象的大小基本上是所需數(shù)據(jù)結(jié)構(gòu)的大小。只有當(dāng)數(shù)據(jù)結(jié)構(gòu)的大小不與高速緩存中的緩沖行對齊時,才增加若干字節(jié)使其對齊。所以,一個Slab上的所有對象的起始地址都必然是按高速緩存中的緩沖行對齊的。參考:深入分析Linux內(nèi)核源碼http://oss.org.cn/kernel-book/   Memcached 源碼分析
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 鹿泉市| 突泉县| 盐津县| 郑州市| 手游| 香格里拉县| 苏州市| 陕西省| 个旧市| 迁西县| 绥德县| 正定县| 河东区| 美姑县| 九江县| 丰顺县| 滁州市| 阳谷县| 响水县| 松原市| 安丘市| 漯河市| 牙克石市| 香格里拉县| 革吉县| 文水县| 巍山| 蕉岭县| 玉溪市| 松阳县| 台前县| 正宁县| 乐都县| 弋阳县| 明溪县| 准格尔旗| 平邑县| 昌邑市| 洞口县| 临武县| 张家港市|