linux内核中如何向slab内存分配器申请内存
在 Linux 内核中,slab 内存分配器是一种高效的内存管理机制,用于管理对象的分配和释放,特别适用于频繁分配和释放固定大小的内存块的场景。slab 分配器为每个缓存创建一个内存池,每个缓存池对应一种对象类型。通过这种方式,它减少了内存碎片并提高了分配效率。
使用 slab 内存分配器分配内存的步骤
-
创建一个 slab 缓存:首先,你需要使用
kmem_cache_create
创建一个 slab 缓存。这是一个描述特定对象类型内存池的结构。 -
从 slab 缓存中分配内存:使用
kmem_cache_alloc
从已经创建的 slab 缓存中分配内存。 -
释放内存:当不再需要这块内存时,使用
kmem_cache_free
释放它。
示例代码:
假设我们要创建一个缓存来管理 struct my_struct
类型的内存对象,并且从中分配内存。
#include <linux/slab.h> // 包含slab相关函数
#include <linux/kernel.h> // 包含 printk
// 定义一个结构体
struct my_struct {
int a;
char b;
};
// 全局变量,保存 slab 缓存的指针
static struct kmem_cache *my_struct_cache = NULL;
// 初始化 slab 缓存
static int __init my_init(void)
{
// 创建 slab 缓存
my_struct_cache = kmem_cache_create("my_struct_cache", sizeof(struct my_struct), 0, SLAB_HWCACHE_ALIGN, NULL);
if (!my_struct_cache) {
printk(KERN_ERR "Failed to create slab cache\n");
return -ENOMEM;
}
printk(KERN_INFO "Slab cache created successfully\n");
return 0;
}
// 分配内存
static void *alloc_my_struct(void)
{
struct my_struct *obj;
// 从 slab 缓存中分配内存
obj = kmem_cache_alloc(my_struct_cache, GFP_KERNEL);
if (!obj) {
printk(KERN_ERR "Failed to allocate memory from slab cache\n");
return NULL;
}
printk(KERN_INFO "Memory allocated from slab cache\n");
return obj;
}
// 释放内存
static void free_my_struct(struct my_struct *obj)
{
// 释放 slab 缓存中的内存
kmem_cache_free(my_struct_cache, obj);
printk(KERN_INFO "Memory freed from slab cache\n");
}
// 模块退出时清理
static void __exit my_exit(void)
{
// 销毁 slab 缓存
if (my_struct_cache) {
kmem_cache_destroy(my_struct_cache);
printk(KERN_INFO "Slab cache destroyed\n");
}
}
module_init(my_init);
module_exit(my_exit);
代码解析
kmem_cache_create
: 这个函数创建了一个 slab 缓存,专门用于管理 struct my_struct
类型的对象。该函数的参数说明:
-
第一个参数是缓存名称 “my_struct_cache”。
-
第二个参数是对象的大小,这里是
sizeof(struct my_struct)
。 -
第三个参数是对齐要求,通常传入 0 即可。
-
第四个参数是标志,SLAB_HWCACHE_ALIGN 让内存块按照 CPU 缓存的要求对齐。
-
第五个参数是构造函数指针,用来初始化每个对象(本例中不需要,因此为 NULL)。
kmem_cache_alloc
: 从创建的 slab 缓存中分配内存。成功时返回内存块的指针,失败时返回 NULL。
kmem_cache_free
: 释放通过 kmem_cache_alloc
分配的内存。
kmem_cache_destroy
: 销毁 slab 缓存,释放与该缓存相关的资源。
注意事项
Slab 缓存可以提高内存分配效率,尤其是在内核中频繁分配和释放固定大小对象时。
需要确保每次分配内存后,都有对应的释放操作,避免内存泄漏。
在创建 slab 缓存时,可以为其指定构造函数和析构函数,分别用于初始化和清理每个对象。