整体上slub的实现比slab更清爽,连带着方便测试和debug
(另:slob分配器因维护困难已从linux代码中删除)
SLAB | SLUB | |
---|---|---|
cpu_cache上缓存的对象 | 以slab中的某个对象为单位,批发到cpu_cache上 | 以整个slab为单位装入cpu_cache上 |
cpu_cache结构 | struct array_cache | struct kmem_cache_cpu |
是否支持着色 | 以cacheline的长度为偏移单位( colour_off ),在将slab对齐到某个大小时,剩余的大小可以满足的cacheline的数量记为colour。每分配一个同类型的slab,就在对象的偏移上加(n%colour)×colour_off的偏移作为着色。 | 不支持(可能是认为没有意义) |
cpu_cache上是否需要为不同node存一个结构 | 需要 | 不需要 |
alloc/free一个非本节点的slab分配的对象时的操作 | alloc: 尝试从其它 node->shared 数组上划一部分对象装到自己的cpu_cache上。 free: 将非本node的对象放在 本node->alien 上,在flush时还回去 | alloc: 直接从其它node分配整个slab free: slab使用期间即使自己的node有了内存,也不会将slab还回去,要等到slab上对象全释放后才可能还回去 |
slab的轮转类型 | 三种:full, partial, free 存在kmem_cache_node上 | 两种:full, partial 存在存在kmem_cache_node上,另外 kmem_cache_cpu本身上存有freeze的slab(kmem_cache_cpu->partial) |
slab管理结构 | 用一个数组来标记下一个free的节点在哪里,这个数组有三种可能的地方: CFLGS_OBJFREELIST_SLAB:所有index的长度不到一个对象的长度,随机选一个对象的位置作为freeindex数组的位置 CFLGS_OFF_SLAB:额外分配内存作为free index数组,条件是剩余的大小不能装下整个free index数组 CFLGS_ON_SLAB:取 slab 的前面部分作为free index数组的位置 | 在个slab对象的后面装一个index。 |
从freelist上取对象的过程 | 数组形式组织直接返回 array_cache->entry[--array_cache->avail] | 由于freelist是类似链表的形式,无法保证原子性,可能需要多次尝试无锁地cas 操作(先取一个free object,再更新下一个free的index,cas查看是否更新成功)。 |
自举初始化过程 | 初始化前后的分配过程写在一起set_up_node | 逻辑分开写更清晰 |
cache对象的清理 | 有定时器触发(见:__initcall(cpucache_init)) | 需要手工触发 |