Linux中的slab分配器講解
Linux最近幾年的發(fā)展迅速,很多中小企業(yè)網(wǎng)站都安裝了Linux操作系統(tǒng)。本文將著重介紹Linux內(nèi)核的內(nèi)存管理,尤其是slab分配提供的機(jī)制。將探索slab分配器背后所采用的思想,并介紹這種方法提供的接口和用法。
slab 緩存
Linux所使用的slab分配器的基礎(chǔ)是Jeff Bonwick為SunOS操作系統(tǒng)首次引入的一種算法。Jeff 的分配器是圍繞對(duì)象緩存進(jìn)行的。在內(nèi)核中,會(huì)為有限的對(duì)象集(例如文件描述符和其他常見結(jié)構(gòu))分配大量?jī)?nèi)存。Jeff發(fā)現(xiàn)對(duì)內(nèi)核中普通對(duì)象進(jìn)行初始化所需的時(shí)間超過了對(duì)其進(jìn)行分配和釋放所需的時(shí)間。
因此他的結(jié)論是不應(yīng)該將內(nèi)存釋放回一個(gè)全局的內(nèi)存池,而是將內(nèi)存保持為針對(duì)特定目而初始化的狀態(tài)。例如,如果內(nèi)存被分配給了一個(gè)互斥鎖,那么只需在為互斥鎖首次分配內(nèi)存時(shí)執(zhí)行一次互斥鎖初始化函數(shù)(mutex_init)即可。后續(xù)的內(nèi)存分配不需要執(zhí)行這個(gè)初始化函數(shù),因?yàn)閺纳洗吾尫藕驼{(diào)用析構(gòu)之后,它已經(jīng)處于所需的狀態(tài)中了。
Linux slab分配器使用了這種思想和其他一些思想來構(gòu)建一個(gè)在空間和時(shí)間上都具有高效性的內(nèi)存分配器。
圖 1 給出了slab結(jié)構(gòu)的高層組織結(jié)構(gòu)。在最高層是cache_chain,這是一個(gè)slab緩存的鏈接列表。這對(duì)于best-fit算法非常有用,可以用來查找最適合所需要的分配大小的緩存(遍歷列表)。cache_chain的每個(gè)元素都是一個(gè) kmem_cache 結(jié)構(gòu)的引用(稱為一個(gè) cache)。它定義了一個(gè)要管理的給定大小的對(duì)象池。
每個(gè)緩存都包含了一個(gè) slabs 列表,這是一段連續(xù)的內(nèi)存塊(通常都是頁(yè)面)。存在 3 種 slab:
slabs_full
完全分配的 slab
slabs_partial
部分分配的 slab
slabs_empty
空slab,或者沒有對(duì)象被分配
注意 slabs_empty 列表中的 slab是進(jìn)行回收(reaping)的主要備選對(duì)象。正是通過此過程,slab 所使用的內(nèi)存被返回給操作系統(tǒng)供其他用戶使用。
slab列表中的每個(gè)slab都是一個(gè)連續(xù)的內(nèi)存塊(一個(gè)或多個(gè)連續(xù)頁(yè)),它們被劃分成一個(gè)個(gè)對(duì)象。這些對(duì)象是從特定緩存中進(jìn)行分配和釋放的基本元素。注意 slab 是 slab分配器進(jìn)行操作的最小分配單位,因此如果需要對(duì)slab進(jìn)行擴(kuò)展,這也就是所擴(kuò)展的最小值。通常來說,每個(gè)slab被分配為多個(gè)對(duì)象。
由于對(duì)象是從slab中進(jìn)行分配和釋放的,因此單個(gè)slab可以在 slab 列表之間進(jìn)行移動(dòng)。例如,當(dāng)一個(gè)slab中的所有對(duì)象都被使用完時(shí),就從slabs_partial 列表中移動(dòng)到 slabs_full 列表中。當(dāng)一個(gè) slab 完全被分配并且有對(duì)象被釋放后,就從 slabs_full 列表中移動(dòng)到 slabs_partial 列表中。當(dāng)所有對(duì)象都被釋放之后,就從 slabs_partial 列表移動(dòng)到 slabs_empty 列表中。
slab背后的動(dòng)機(jī)
與傳統(tǒng)的內(nèi)存管理模式相比, slab緩存分配器提供了很多優(yōu)點(diǎn)。首先,內(nèi)核通常依賴于對(duì)小對(duì)象的分配,它們會(huì)在系統(tǒng)生命周期內(nèi)進(jìn)行無數(shù)次分配。slab 緩存分配器通過對(duì)類似大小的對(duì)象進(jìn)行緩存而提供這種功能,從而避免了常見的碎片問題。slab分配器還支持通用對(duì)象的初始化,從而避免了為同一目而對(duì)一個(gè)對(duì)象重復(fù)進(jìn)行初始化。最后,slab分配器還可以支持硬件緩存對(duì)齊和著色,這允許不同緩存中的對(duì)象占用相同的緩存行,從而提高緩存的利用率并獲得更好的性能。
【編輯推薦】