初识slub分配器

在页分配器之上就是我们熟悉的slub分配器了。

slub分配器的出现很容易理解

毕竟不是谁都需要以页为单位申请内存
将申请对象按照大小分类,减少内部碎片
增加了调试功能

从API开始

先来看看平时要怎么使用slub。没见过猪跑,猪肉估计还是吃过的。

最常用的就是这一组了

kmalloc
kfree

内核对普通的内存分配预设了指定大小的slub分配器。所以当我们使用这一组API时,内核会根据我们需要分配的大小找到合适的块来分配。

除此之外还有一组API可以帮助我们定义自己制定的slub分配器

kmem_cache_create
kmem_cache_alloc
kmem_cache_free

当我们使用这一组API的时候,内核就会专门给我们增加一个slub分配器,后续的内存会专门由这个分配器分配。

一个栗子

光说不练假把式,那我们现在就来看看一个具体的例子~

#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");

#define ALLOC_NUM 32

static struct kmem_cache *test_cache;
void* tmp[ALLOC_NUM];

static void init_once(void *foo)
{
    static int num;
    printk(KERN_ERR "%s: [%02d]%p is created\n", __func__, num++, foo);
}

static int kmem_cache_test_init(void)
{
    int i;
    test_cache = kmem_cache_create("test_cache", 1234, 4,
            0, init_once);
    if (test_cache == NULL)
        return -ENOMEM;

    printk(KERN_ERR "%s: Fetch a cache from kmem_cache\n", __func__);
    for (i = 0; i < ALLOC_NUM; i++)
        tmp[i] = kmem_cache_zalloc(test_cache, GFP_KERNEL);

    return 0;
}
static void kmem_cache_test_exit(void)
{
    int i;
    for (i = 0; i < ALLOC_NUM; i++)
        kmem_cache_free(test_cache, tmp[i]);
    kmem_cache_destroy(test_cache);
}
module_init(kmem_cache_test_init);
module_exit(kmem_cache_test_exit);

这个例子非常简单

新建一个名为test_cache的slub分配器
从这个slub分配器中分配了32个对象
每个对象都有一个构造函数

这就是一个非常简单的内核模块,大家可以在自己的linux系统上编译运行。亲测,可用。

话说很久以前我还修复过一个slub中构造函数的一个bug。当时的版本中第一个对象会被构造两次。这个问题由这个补丁修复

简单观测

系统中一共有两个地方可以观测到slub的情况。

/proc/slabinfo
/sys/kernel/slab/xxx/

比如我们cat /proc/slabinfo能够得到

slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
test_cache            52     52   1248   26    8 : tunables    0    0    0 : slabdata      2      2      0

这个输出的格式确实有点丑,不知道哪天哪位高手可以整好看一点。

从这个输出的结果可以看到,现在一共有52个test_cache的对象,实际上我们只分配了32个不是?这也是slub的工作之一,会预先多分配一些对象,而不是每次重新分配。

当然这个文件还可以查看究竟那个模块,哪个部分用的内存最多。你说是不是?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值