linux kernel 內存管理是個很大的話題,這里記錄一點個人關於slab模塊的一點思考總結。
有些書把slab介紹成高速緩存,這會讓人和cache,特別是cpu cache混淆,造成誤解。slab最開始的目的是解決頻繁內存分配的效率問題,所以把頻繁分配回收的對象,預先分配並初始化好,后面的對象分配回收主要就是對象管理數據的維護工作。
linux kernel 通過把整個物理內存划分成以一個個page進行管理,管理器就是伙伴系統,它的最小分配單元就是page。但是對於小於page的內存分配,如果直接分配一個page,是一個很大的浪費。linux kernel 通過slab來實現對小於page大小的內存分配。slab把page按2的m次冪進行划分一個個字節塊,當kmalloc申請內存時,通過slab管理器返回需要滿足申請大小的最小空閑內存塊。
slub主要是針對slab的對象管理數據的優化版本,相比於slab,slub提供更小的管理成本開銷。而且slub對多核系統的支持也更加友好。細節這里就不展開講。
所以kernel的內存管理是個2層分層系統,從下往上依次為:
- 第一層為全部物理內存:其管理器為伙伴系統,最小管理單位為page;
- 第二層為slab page:其管理器為slab/slub,最小管理單位為2的m次冪的字節塊;
另外為了解決多核和NUMA架構下效率問題,slab管理器kmem_cache又把slab page對象分為2層結構,從下往上依次為:
- 第一層為NUMA node下cpu共享page:管理器為kmem_cache_node,管理node下的slab對象,解決NUMA架構的內存訪問效率問題。當本層的空閑page不足時,從伙伴系統申請空閑page;
- 第二層為per-cpu專屬page:管理器為kmem_cache_cpu,管理cpu專屬的slab對象,解決多核競爭問題。當本層的空閑page不足時,從第一層申請空閑page;
可以看出,kernel內存管理大量使用了分層抽象的思想,這也是軟件設計中控制復雜度最常見的手段。
--EOF--