slab内存分配器

发布于 2008-06-20 16:43:10
slab内存分配器[DragonFlyBSD版本]

DragonFlyBSD的内核内存分配采用了slab分配器,相应的代码文件是kern_slaballoc.c和slaballoc.h。

1、slab内存分配器把内存划分为小内存分配和大内存分配,两者的策略并不相同。

2、代码中的slab结构
根据系统总的内存大小,选择合适的zone大小(每个zone的大小都是相同的,一般为2^n个page)
对于一个特定的zone,在上面分配的chunk大小是固定的(即zone中,除了zone本身结构体中占用的大小外,剩余的内存被划分为相同大小的chunk,chunk即通常意义上分配出去的内存块)
而不同chunk大小的zone放在一个zone数组链表中管理,zone数组一般是128, 256, 512, 1024, 2048...chunk大小的zone方式排列。

zone结构中包括:chunk size,freed chunk,UIndex及UEndIndex(初始时UIndex指向第一个chunk), UIndexMax等

3、小内存分配:
当需要分配一块大小为size的小内存时,
分配器先根据size获得是哪种zone,然后取zone数组链表的表头,如果存在
先检查是否有freed chunk,如果有分配之,否则分配UIndex,并把UIndex指向下一个项(如果UIndex到达UEndIndex,那么表示这个zone中的chunk已经分配完毕,需要把这个zone从zone数组链表中移除)

如果zone数组链表表头是空,那么需要新分配一块zone空间(先在系统的freed zones链表中查找是否有空闲zone,否则采用大内存分配策略),把它的第一块chunk分配出去并把新分配的zone放到zone数组链表中维护。

4、小内存释放
根据是否小内存地址获得相应zone的地址(因为zone的分配是zone对齐的),把小内存放到freed chunk链表中,如果freed chunk链表数目达到这个zone中最大chunk数目时(意味着这个zone是全部空闲的),把这个zone放到freed zones链表中。如果freed zones链表的数目超过一定数值时(例如2),把多余的空闲zone给释放掉(通过大内存释放方式)

5、大内存分配释放策略
直接按照page的整数倍进行分配释放;

大内存分配、释放需要考虑的一个问题:当需要释放一块内存时,如何知道这块内存是大内存还是小内存?

方法:用一个kmemusage数组记录每个page的使用方式(如果1GB内存,需要1M空间记录其状态)。大内存分配时,需要在kmemusage相应项中记录使用了多少个page数,释放时再把这个page数清为零。

6、多核的考虑
zone列表在每个CPU的存放一份,释放时,如果释放了另一CPU管理的chunk,可以通过发消息的形式给此CPU然后由此CPU释放掉。

7、slab算法的体现
slab分配的object即chunk,释放后将先保存在相应zone的freed chunk列表中,这样就实现了object的cache。
但对于在对象分配时进行对象自动构造,此功能似乎不在DragonFlyBSD代码中。

查看更多

关注者
0
被浏览
3.6k
1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友