Slob分配器相較Slab和Slub分配器而言,最大的特點就是簡潔,其總共的實現代碼大概就600多行,因此其適用於嵌入式系統。不同於Slab和Slub,Slob分配器沒有引入本地CPU高速緩存和本地節點的概念。Slob分配器同樣使用鏈表來管理slob,不過總共只存在三個全局partial_free鏈表,這三個鏈表是按對象大小來劃分的。
相關閱讀:
Linux Slob分配器(二)--分配對象 http://www.linuxidc.com/Linux/2012-07/64108.htm
Linux Slob分配器(三)--釋放對象 http://www.linuxidc.com/Linux/2012-07/64109.htm
對於小於256字節的對象,將從free_slob_small鏈表中尋找slob進行分配
對於小於1024字節的對象,將從free_slob_medium鏈表中尋找slob進行分配
對於大於1024字節的對象,將從free_slob_large鏈表中尋找slob進行分配
對於大於PAGE_SIZE的對象,將直接通過伙伴系統分配,不經手Slob分配器
那麼總共只有三個鏈表,Slob分配器的各類緩存怎麼管理自己的空閒對象呢?實際上,所謂的不同類別的緩存都只是偽緩存,因為它們並沒有專屬自己的內存。當你在Slob分配器中創建一個緩存時,只是聲明了該緩存的對象的大小size、對齊值align等,那麼當要從該緩存分配對象時,將會根據size定位到相應的鏈表,尋求分配。因此專用緩存分配對象(kmem_cache_alloc())和普通緩存分配對象(kmalloc())並無太多區別,它們的對象都來源於這三個鏈表,只不過內核欺騙性的保留了這些接口而已。由此可以想象,struct kmem_cache這個結構在Slob分配器中是很簡潔的
接下來的一個問題就是Slob分配器是如何描述slob的。在Slob分配器中,一個slob永遠都是占用一個頁框的大小,所以對於大於PAGE_SIZE的對象,會選擇直接通過伙伴系統分配。Slob分配器將所有的slob組織在三個全局鏈表中,不過,這些slob的描述結構都不需要進行額外的分配。Slob分配器將描述slob的變量打包成一個結構,然後和頁描述符struct page一起組成一個聯合體,這樣就可以直接利用頁描述符已占有的空間,將頁描述符中無關緊要的字段填充為slob的有效描述字段,這樣便可以省下一筆內存了!
我們可以看到,實際上真正用於slob管理的項只有三個,即units,free和list.
free和list的意義已經很清楚明了了,現在來解釋下slobidx_t units這個玩意。unit是slob的粒度,也就是說當你分配內存時,必須分配出去N個unit,所有的管理都是基於unit的。unit的大小根據PAGE_SIZE的不同而不同,通常情況下為2個字節,關於unit大小的定義:
既然slob的管理是基於unit的,那麼units字段的含義也就很容易理解了,它表示的是slob中當前還剩余的空閒單元數目。