码迷,mamicode.com
首页 > 其他好文 > 详细

memslab源码阅读总结

时间:2015-09-01 21:36:49      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:

Memslab从结构上可以分为三层,

1最顶层是一些cache队列,

2 每个cache队列中又包含三个slab队列,

3 每个slab管理着一个页面

 

我们首先从这三层来介绍memslab的整体结构

 

1 cache队列

最顶层与cache相关的队列有

  1. Ikmem_array: 指向不同大小的cache
  2. Ikmem_lookup: 将cache按照从大到小的顺序排列组成的数组
  3. Ikmem_size_lookup1: 以4为间隔的大小(范围从4到1024),每个指向第一个大于自身大小的cache
  4. Ikmem_size_lookup2: 以1k为间隔的大小(范围从1k到256k),每个指向第一个大于自身大小的cache
  5. ikmem_large_ptr: 存放大于128k的页面

 

1.1 ikmem_array和ikmem_lookup数组

Memslab中用来存放cache结构的是ikmem_array数组和ikmem_lookup数组, 这两个数组被放在一块大小为2* sizelimit 大小的内存上, size_limit会随着ikmem_array的大小而变化,

在ikmem_init中,创建2^16, 2^15 … 2^3共14个cache,ikmem_array和ikmem_lookup都指向这些cache,只不过ikmem_lookup中cache是按照从大到小的顺序排列的

 技术分享

1.2 Ikmem_size_lookup1和Ikmem_size_lookup2数组

Ikmem_size_looup1: 以4为间隔的大小(范围从4到1024),每个指向第一个大于自身大小的cache

 技术分享

 

Ikmem_size_lookup2: 以1k为间隔的大小(范围从1k到256k),每个指向第一个大于自身大小的cache, 超过2^16的大小指向NULL

 技术分享

 

2 cache

Cache中比较重要的结构是imemlru_t array, array中会有一个entry放着刚刚被应用返回的slab中的对象,slab中的对象被返回后不会直接返回给slab,而是先放在这个数组中

以及三个slab的链表:slabs_partial, slabs_full, slabs_free, slabs_partial存放的slabs中的对象被部分分配出去,slabs_full中的对象被全部分配出去,slabs_free中的对象完全没有被分配出去

3 slab

每个slab管理着一个页面,按照obj_size将页面分为obj1, obj2 …,在未分配的时候每个对象的开头都指向下一个对象的地址,bufctl指向这个待分配链表的头部

 技术分享

分配算法,是一种使用单链表去管理页面空间的方式,每次分配头指针bufctl指向的页面,将bufctl指向下一个对象,对象被应用释放返回时,将对象加入链表头部,原理类似下图所示

 技术分享

 

主要的函数为ikmem_init, ikmem_malloc和ikmem_free,我们从malloc和free入手,去看一看其中的流程:

 

1 Ikmem_malloc:

 技术分享

分配时, 如果需要分配的大小小于1024, 首先在ikmem_size_lookup1中查找, 否则在ikmem_size_lookup2中寻找cache,

 技术分享

如果在ikmem_size_lookup1以及ikmem_size_lookup2中没有与size相同大小的cache, 就从ikmem_lookup中找到第一个比size大的cache

 技术分享

 

当所需要的size大于之前准备的2^16大小的页面, malloc一个页面, 并加入ikmem_large_ptr队列

 

如果在ikmem_size_lookup1或是在ikmem_size_lookup2中发现了需要的cache, 调用imemcache_alloc函数, 从这个cache中分配一个对象

1.1 Ikmem_malloc->imemcache_alloc:

 技术分享

程序会先去看该cache中的array有没有空余的对象, cache中的array存放着刚刚被从应用释放回来的页面, 刚释放回来的页面不会立刻放回其所属的slab, 而会放入array, 与其他刚被释放的页面形成链表, 这样的好处是避免了每次去slab中分配页面, 并且还要调整slab所属的队列,

如果array中缓存的对象为空, 就会调用imemcache_fill_batch, 从slab队列中分配batchcount个对象到array中, 然后返回这个对象

 技术分享

从cache中分配出去的对象的大小会被加到总的分配出去的大小ikmem_inuse上

 

2 ikmem_free:

 技术分享

首先判断, 如果分配的对象是一个在大页面的对象, 就从ikmem_large_ptr队列中删除这个对象, 并且free掉这个对象

 技术分享

否则的话, 调用imemcache_free去释放这个对象, 释放完后, 同样要从ikmem_inuse中减去这个释放回来的大小

 

2.2 Ikmem_free -> imemcache_free:

 技术分享

释放回来的页面会首先放到array中去,

 技术分享

如果array中的对象的数目超过了array->limit的大小, 程序会调用imemcache_list_free, 这个对象就会被放回slab中, 并且程序会调整slab所在的slab队列, 比如原先在slab_free中的slab, 由于对象被返回, 就会被调整到slab_partial中

 技术分享

如果cache中空闲的slab超过了一定数量(cache->free_limit), cache就会调用imemcache_drain_list, 去释放掉一半数量的空闲对象

memslab源码阅读总结

标签:

原文地址:http://www.cnblogs.com/zhangfann/p/4776851.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!