Linux slab分配器剖析
slab,或者没有对象被分配
注意 slabs_empty 列表中的 slab 是进行回收(reaping)的主要备选对象.正是通过此过程,slab 所使用的内存被返回给操作系统供其他用户使用. slab 列表中的每个 slab 都是一个连续的内存块(一个或多个连续页),它们被划分成一个个对象.这些对象是从特定缓存中进行分配和释放的基本元素.注意 slab 是 slab 分配器进行操作的最小分配单位,因此如果需要对 slab 进行扩展,这也就是所扩展的最小值.通常来说,每个 slab 被分配为多个对象. 对象是从 slab 中进行分配和释放的,因此单个 slab 可以在 slab 列表之间进行移动.例如,当一个 slab 中的所有对象都被使用完时,就从 slabs_partial 列表中移动到 slabs_full 列表中.当一个 slab 完全被分配并且有对象被释放后,就从 slabs_full 列表中移动到 slabs_partial 列表中.当所有对象都被释放之后,就从 slabs_partial 列表移动到 slabs_empty 列表中. slab 背后的动机 与传统的内存管理模式相比, slab 缓存分配器提供了很多优点.,内核通常依赖于对小对象的分配,它们会在系统生命周期内进行无数次分配.slab 缓存分配器通过对类似大小的对象进行缓存而提供这种功能,从而避免了常见的碎片问题.slab 分配器还支持通用对象的初始化,从而避免了为同一目而对一个对象重复进行初始化.,slab 分配器还可以支持硬件缓存对齐和着色,这允许不同缓存中的对象占用相同的缓存行,从而提高缓存的利用率并获得更好的性能.
API 函数 现在来看一下能够创建新 slab 缓存、向缓存中增加内存、销毁缓存的应用程序接口(API)以及 slab 中对对象进行分配和释放操作的函数. 第一个步骤是创建 slab 缓存结构,您可以将其静态创建为: struct struct kmem_cache *my_cachep; slab 缓存的 Linux 源代码 您可以在 ./linux/mm/slab.c 中找到 slab 缓存的源代码. kmem_cache 结构也是在 ./linux/mm/slab.c 中定义的.本文着重讨论 2.6.21 Linux 内核中的当前实现. 然后其他 slab 缓存函数将使用该引用进行创建、删除、分配等操作.kmem_cache 结构包含了每个中央处理器单元(CPU)的数据、一组可调整的(可以通过 proc 文件系统访问)参数、统计信息和管理 slab 缓存所的元素. kmem_cache_create 内核函数 kmem_cache_create 用来创建一个新缓存.这通常是在内核初始化时执行的,或者在首次加载内核模块时执行.其原型定义如下: struct kmem_cache * kmem_cache_create( const char *name, size_t size, size_t align, unsigned long flags; void (*ctor)(void*, struct kmem_cache *, unsigned long), void (*dtor)(void*, struct kmem_cache *, unsigned long)); name 参数定义了缓存名称,proc 文件系统(在 /proc/slabinfo 中)使用它标识这个缓存. size 参数指定了为这个缓存创建的对象的大小, align 参数定义了每个对象必需的对齐. flags 参数指定了为缓存启用的选项.这些标志如表 1 所示. 表 1. kmem_cache_create 的部分选项(在 flags 参数中指定)
ctor 和 dtor 参数定义了一个可选的对象构造器和析构器.构造器和析构器是用户提供的回调函数.当从缓存中分配新对象时,可以通过构造器进行初始化. 在创建缓存之 |
||||||||
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |