[Happy GLIB] glib的slab算法实现学习

slab提出来是为了解决内部内存碎片的问题,在linux内核中与buddy system一起来解决内核内存管理。但是要看懂slab在linux内核中的实现当前有些困难,我们不如拿些容易阅读的代码来了解slab算法的运作过程。GLIB库实现非常clear,可以做为slab算法的实现学习的入门。
slab在GLIB中的实现相关文件是gslice.h/c,但是在这个实现文件中,有更复杂的,支持多线程更多的magazine caching算法。

<strong>0. slab算法的运作机理</strong>
关于slab算法的运作机理,可以查看 wiki


1. slab结构体定义
struct _ChunkLink {
ChunkLink *next;
ChunkLink *data;
};
struct _SlabInfo {
ChunkLink *chunks;
guint n_allocated;
SlabInfo *next, *prev;
};



从结构体可以知道,每个slab维护着前面slab的link prev和后面的slab的link prev,可知它们链接起来就是一个双向环形链表(slab ring)。除此之外,还维护着一个chunk指针,用来指向free chunk的单向链表。


2. allocator结构体定义
...
/* slab allocator */
GMutex slab_mutex;
SlabInfo **slab_stack; /* array of MAX_SLAB_INDEX (allocator) */
guint color_accu;
} Allocator;


从数据结构可知,全局变量allocator会维护着一个指针数组,成员为SlabInfo*指针,指向一个环形slab双向链表,也即前面介绍的slab ring。每个成员的slabinfo*指向的slab ring所管理的chunks,size都必须是相同的,例如第一个slab ring里面的chunk全部都是8 (bytes),第二个slab ring里全部都是8*2 (bytes),以此类推,一直到最大的chunk size。 初始化时,所有的成员都会初始化为null,代表当前slab system没有free list。


3. slab内存请求操作的过程
static gpointer
slab_allocator_alloc_chunk (gsize chunk_size)
{
ChunkLink *chunk;
guint ix = SLAB_INDEX (allocator, chunk_size); // 找到chunk_size所对应的slab slot
/* ensure non-empty slab */
// 如果没有free list,则预先分配一页来填充此slot(一页可能会有很多chunks)
if (!allocator->slab_stack[ix] || !allocator->slab_stack[ix]->chunks)
allocator_add_slab (allocator, ix, chunk_size);
/* allocate chunk */
// 分配第一个chunk给client,后面的chunks挂接到当前slab上
chunk = allocator->slab_stack[ix]->chunks;
allocator->slab_stack[ix]->chunks = chunk->next;
allocator->slab_stack[ix]->n_allocated++;
/* rotate empty slabs */
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值