宋牧春: 多图详解Linux内存分配器slub

本文由宋牧春撰写,深入解析Linux内存分配器slub。内容涵盖slub数据结构、它们之间的关系、内存分配及释放原理,以及kmalloc的使用。
摘要由CSDN通过智能技术生成
本文目录:

1. 前言

2. slub数据结构

3. slub数据结构之间关系

4. slub分配内存原理

5. slub释放内存原理

6. kmalloc

作者简介:

宋牧春,linux内核爱好者,2017年6月本科毕业于江苏大学。现就职于一家手机研发公司,任职BSP驱动工程师,主要负责TP驱动bringup和调试。

1. 前言

Linux中,伙伴系统(buddy system)是以页为单位管理和分配内存。但是现实的需求却以字节为单位,假如我们需要申请20Bytes,总不能分配一页吧!那岂不是严重浪费内存。那么该如何分配呢?slab分配器就应运而生了,专为小内存分配而生。slab分配器分配内存以Byte为单位。但是slab分配器并没有脱离伙伴系统,而是基于伙伴系统分配的大内存进一步细分成小内存分配。

前段时间学习了下slab分配器工作原理。因为自己本身是做手机的,发现现在好像都在使用slub分配器,想想还是再研究一下slub的工作原理。之前看了代码,感觉挺多数据结构和成员的。成员的意思是什么?数据结构之间的关系是什么?不知道你是否感觉云里雾里。既然代码阅读起来晦涩难懂,如果有精美的配图,不知是否有助于阁下理解slub的来龙去脉呢?我想表达的意思就是文章图多,图多,图多。我们只说原理,尽量不看代码。因为所有代码中包含的内容我都会用图来说明。你感兴趣绝对有助于你看代码。

注:文章代码分析基于linux-4.15.0-rc3

2. slub数据结构

slub的数据结构相对于slab来说要简单很多。并且对外接口和slab兼容。所以说,从slab的系统更换到slub,可以说是易如反掌。


2.1. kmem_cache


现在假如从伙伴系统分配一页内存供slub分配器管理。对于slub分配器来说,就是将这段连续内存平均分成若干大小相等的object(对象)进行管理。可是我们总得知道每一个objectsize吧!管理的内存页数也是需要知道的吧!不然怎么知道如何分配呢!因此需要一个数据结构管理。那就是structkmem_cachekmem_cache数据结构描述如下:

struct kmem_cache {

    struct kmem_cache_cpu __percpu *cpu_slab;

    /* Used for retriving partial slabs etc */

    slab_flags_t flags;

    unsigned long min_partial;

    int size;             /* The size of an object including meta data */

    int object_size;     /* The size of an object without meta data */

    int offset;           /* Free pointer offset. */

#ifdef CONFIG_SLUB_CPU_PARTIAL

    int cpu_partial;      /* Number of per cpu partial objects to keep around */

#endif

    struct kmem_cache_order_objects oo;

    /* Allocation and freeing of slabs */

    struct kmem_cache_order_objects max;

    struct kmem_cache_order_objects min;

    gfp_t allocflags;    /* gfp flags to use on each alloc */

    int refcount;         /* Refcount for slab cache destroy */

    void (*ctor)(void *);

    int inuse;            /* Offset to metadata */

    int align;            /* Alignment */

    int reserved;         /* Reserved bytes at the end of slabs */

    const char *name;    /* Name (only for display!) */

    struct list_head list;  /* List of slab caches */

    struct kmem_cache_node *node[MAX_NUMNODES];

};

  • cpu_slab:一个per cpu变量,对于每个cpu来说,相当于一个本地内存缓存池。当分配内存的时候优先从本地cpu分配内存以保证cache的命中率。

  • flagsobject分配掩码,例如经常使用的SLAB_HWCACHE_ALIGN标志位,代表创建的kmem_cache管理的object按照硬件cache 对齐,一切都是为了速度。

  • min_partial:限制struct kmem_cache_node中的partial链表slab的数量。虽说是mini_partial,但是代码的本意告诉我这个变量是kmem_cache_nodepartial链表最大slab数量,如果大于这个mini_partial的值,那么多余的slab就会被释放。

  • size:分配的object size

  • object_size:实际的object size,就是创建kmem_cache时候传递进来的参数。和size的关系就是,size是各种地址对齐之后的大小。因此,size要大于等于object_size

  • offsetslub分配在管理object的时候采用的方法是:既然每个object在没有分配之前不在乎每个object中存储的内容,那么完全可以在每个object中存储下一个object内存首地址,就形成了一个单链表。很巧妙的设计。那么这个地址数据存储在object什么位置呢?offset就是存储下个object地址数据相对于这个<

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值