Object Construction
经典的slab allocator在slab创建的时候给slab中的每个object应用constructor。这样当从slab中申请object的时候,拿到的object都是初始化好的。但是我们看这样一个极端的情况:假设每个object是8个字节大小,如果一个slab含有一个8K的页面,那一个slab可以容纳1024个object,如果该object的构造函数中为每个object申请1K 内存,那当这个 slab创建的时候一共分配了1M的内存。但是如果这个slab中只有很少的一部分object被实际使用,那很多的内存就被浪费了!
当引入magazine之后,solaris的策略是:
- slab中维护raw buffer,将object construction操作从slab layer上升到magazine layer中进行。
- 在 buffer 进入到magazine layer的时候进行construction。
- 当object 从magazine 还回slab layer时进行destruction,从而变成raw buffer。
不能迷信别人说的话,我们来看看实际的代码:umem_cache_alloc
//情况4:从magazine layer分配full magazine失败, 我们试图slab layer取一块raw buffer
buf = umem_slab_alloc(cp, umflag); //注意,返回的buffer是没有应用过构造函数的
…
if (cp->cache_flags & UMF_BUFTAG) {
//Let umem_cache_alloc_debug() apply the constructor for us.
if (umem_cache_alloc_debug(cp, buf, umflag) == -1) {
if (umem_alloc_retry(cp, umflag)) {
goto retry;
}
return (NULL);
}
return (buf); //一切顺利的话,返回构造好的object。
}
注意到在umem_cache_alloc的情况4中并没有分配full magazine的代码哦!那full magazine是怎么产生的呢?首先我们要区分两个概念:
- Object Allocation: 在分配时,如果depot layer没有full magazine了,我们直接从slab layer取并应用constructor.
- Magazine Allocation: 在释放时,如果depot没有empty magazine,我们分配一个magazine。
Magazine只是一个管理容器。我们从不显式的分配full magazine,因为这没有必要 。当application释放objects的时候,就会将empty magazine填充成full magazine。
来看一下umem_cache_free 的代码:
_umem_cache_free(umem_cache_t *cp, void *buf)
{
…
for(;;){
//情况1:当前magazine不是full magazine ,直接把object归还
//情况2:当前magazine是full但是previous magazine为空,交换cur和prev后重试
//情况3:cur和prev magazine都是full,从depot上取一个empty magazine…
…
//情况4: 1,2,3都失败了以后,试图分配empty magazine
umem_magazine_t *emp = _umem_cache_alloc(mtp->mt_cache,UMEM_DEFAULT);
if(emp!=NULL)
{
umem_depot_free(cp, &cp->cache_empty,emp); //将分配的 empty magazine加到depot中
continue; //重试,于是下一轮会落入情况3
}
break; //如果分配empty magazine都失败了,我们只好调用slab_free直接返回给slab了。
}
umem_slab_free(cp,buf);
}
对于为什么从不显式分配full magazine我不是非常理解。我的猜测是:magazine其实是个容器,所谓full magazine,不过是先分配empty magazine,然后预先填充M个objects。如果 magazine的rounds=M,相当于要事先调用M次constructor,而其中M-1次都是负担。但是如果没有分配full magazine,就会使得cache miss rate上升啊??希望有同学可以解答我的疑问-:)
本文探讨了SOLARIS操作系统中slab分配器的优化策略,特别是如何通过引入magazine机制减少内存浪费,并分析了umem_cache_alloc和umem_cache_free函数的具体实现。

7775

被折叠的 条评论
为什么被折叠?



