作为一种出名的设计及算法 Slab 已经很早就出现在各大系统中了,Linux 也实现了 Slab,那 Slab 一般作什么用途?解决了什么问题?如何实现?为什么要这样实现?这就是今天要讨论的内容了。
我们知道 Buddy 系统解决了物理内存分配的外碎片问题,但由于粒度太大,都是以页为单位,显然用起来有些浪费,当如果要申请一些小的内存,并且会频繁的申请相同数据结构的内存来存储一些内核中的数据时,这时 Slab 便应运而生了。在内核中,经常会使用一些链表,链表中会申请许多相同结构的结构体,比如文件对象,进程对象等等,如果申请比较频繁,那么为它们建立一个内存池,内存池中都是相同结构的结构体,当想申请这种结构体时,直接从这种内存池中取一个结构体出来,想必是有用且速度极快的。一个物理页就可以作用这种内存池的载体,进而进行充分利用,减少了内碎片的产生。
所以,首先,Slab 相当于内存池是思想,且是为了解决内碎片而产生的。
我们知道 Buddy 系统解决了物理内存分配的外碎片问题,但由于粒度太大,都是以页为单位,显然用起来有些浪费,当如果要申请一些小的内存,并且会频繁的申请相同数据结构的内存来存储一些内核中的数据时,这时 Slab 便应运而生了。在内核中,经常会使用一些链表,链表中会申请许多相同结构的结构体,比如文件对象,进程对象等等,如果申请比较频繁,那么为它们建立一个内存池,内存池中都是相同结构的结构体,当想申请这种结构体时,直接从这种内存池中取一个结构体出来,想必是有用且速度极快的。一个物理页就可以作用这种内存池的载体,进而进行充分利用,减少了内碎片的产生。
所以,首先,Slab 相当于内存池是思想,且是为了解决内碎片而产生的。
我们看一下 Slab 算法的结构图。
即使是专有结构的内存池,所以一个高速缓存即 kmem_cache ,就代表一个结构体的内存池,它有一个每 CPU 数据 array, 进一步加快了申请速度,解决了多 CPU 加锁,且小数据缓存的目的,因为保留少量的频繁申请和释放得来的空间,等下次申请时直接从这里取得,由于结构简单,所以速度极快。所以每一个 CPU 都会对应一个 array_cache 结构体,在内存布局上,该结构体后面,紧接着有一