Slab对象的分配和回收kmem_bufctl_t的用法
2008-12-29 23:36
253 查看
在这里我介绍一下Slab对象的分配和回收kmem_bufctl_t的用法,首先要说明的一点
是Slab缓存的内存布局,Slab缓存分为两部分,一部分是用于管理Slab对象,另一
部分是Slab对象本身,针对这两部分内容,Slab缓存的内存布局大概有两种:
1. Slab对象同管理Slab对象的缓存一起存放。
2. 分开存放。
对于管理区分成2部分,一部分是描述Slab的数据结构,struct slab。另外一部分是用于
描述Slab对象的offset的一个数组,叫做kmem_bufctl_t。
管理区:Slab struct|kmem_bufctl_t array
如何取得kmem_bufctl_t数组的首地址:
static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
{
return (kmem_bufctl_t *) (slabp + 1);
}
从代码上很容易看清楚,这个数组是存放在Slab struct之后的。
对于Slab struct中的一个字段free是用来记录当前可用的object的一个索引值。
我们来看一下Slab对象分配函数
static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slabp, int nodeid)
{
s_mem是指向Slab对象的内存起始地址,buffer_size是对象的大小包括colour offset.
void *objp = slabp->s_mem + (slabp->free * cachep->buffer_size);
kmem_bufctl_t next;
slabp->inuse++;
取得当前可用的Slab对象的位置。
next = slab_bufctl(slabp)[slabp->free];
将当前可用的slab对象的位置下移一个。
slabp->free = next;
return objp;
}
再来看一下Slab对象的释放函数
static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp, void *objp,
int nodeid)
{
首先求的Slab对象的索引值。
unsigned int objnr = (unsigned)(objp-slabp->s_mem) / cachep->buffer_size;
根据索引值在kmem_bufctl_t中寻找将要释放对象的kmem_bufctl_t数组中的位置的值,将下一个
对象的索引值付值给他。即将要释放的对象插回数组。
slab_bufctl(slabp)[objnr] = slabp->free;
重置当前可以供分配的索引值
slabp->free = objnr;
slabp->inuse--;
}
最后再来看一下初始化Slab对象的函数
static void cache_init_objs(struct kmem_cache *cachep,
struct slab *slabp, unsigned long ctor_flags)
{
int i;
for (i = 0; i < cachep->num; i++) {
void *objp = slabp->s_mem + cachep->buffer_size * i;
如果存在构造函数,需要调用构造函数
if (cachep->ctor)
cachep->ctor(objp, cachep, ctor_flags);
当前Slab对象的bufferctl值为下一个Slab的索引值。
slab_bufctl(slabp)[i] = i + 1;
}
slab_bufctl(slabp)[i - 1] = BUFCTL_END;
当前可用的Slab对象的索引值为0,表示第一个对象
slabp->free = 0;
}
是Slab缓存的内存布局,Slab缓存分为两部分,一部分是用于管理Slab对象,另一
部分是Slab对象本身,针对这两部分内容,Slab缓存的内存布局大概有两种:
1. Slab对象同管理Slab对象的缓存一起存放。
2. 分开存放。
对于管理区分成2部分,一部分是描述Slab的数据结构,struct slab。另外一部分是用于
描述Slab对象的offset的一个数组,叫做kmem_bufctl_t。
管理区:Slab struct|kmem_bufctl_t array
如何取得kmem_bufctl_t数组的首地址:
static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
{
return (kmem_bufctl_t *) (slabp + 1);
}
从代码上很容易看清楚,这个数组是存放在Slab struct之后的。
对于Slab struct中的一个字段free是用来记录当前可用的object的一个索引值。
我们来看一下Slab对象分配函数
static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slabp, int nodeid)
{
s_mem是指向Slab对象的内存起始地址,buffer_size是对象的大小包括colour offset.
void *objp = slabp->s_mem + (slabp->free * cachep->buffer_size);
kmem_bufctl_t next;
slabp->inuse++;
取得当前可用的Slab对象的位置。
next = slab_bufctl(slabp)[slabp->free];
将当前可用的slab对象的位置下移一个。
slabp->free = next;
return objp;
}
再来看一下Slab对象的释放函数
static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp, void *objp,
int nodeid)
{
首先求的Slab对象的索引值。
unsigned int objnr = (unsigned)(objp-slabp->s_mem) / cachep->buffer_size;
根据索引值在kmem_bufctl_t中寻找将要释放对象的kmem_bufctl_t数组中的位置的值,将下一个
对象的索引值付值给他。即将要释放的对象插回数组。
slab_bufctl(slabp)[objnr] = slabp->free;
重置当前可以供分配的索引值
slabp->free = objnr;
slabp->inuse--;
}
最后再来看一下初始化Slab对象的函数
static void cache_init_objs(struct kmem_cache *cachep,
struct slab *slabp, unsigned long ctor_flags)
{
int i;
for (i = 0; i < cachep->num; i++) {
void *objp = slabp->s_mem + cachep->buffer_size * i;
如果存在构造函数,需要调用构造函数
if (cachep->ctor)
cachep->ctor(objp, cachep, ctor_flags);
当前Slab对象的bufferctl值为下一个Slab的索引值。
slab_bufctl(slabp)[i] = i + 1;
}
slab_bufctl(slabp)[i - 1] = BUFCTL_END;
当前可用的Slab对象的索引值为0,表示第一个对象
slabp->free = 0;
}
相关文章推荐
- 内存管理-SLAB(分配SLAB对象kmem_cache_alloc())
- Java虚拟机学习 - 对象内存分配与回收
- jvm学习记录--06 垃圾回收对象内存分配策略
- 物理内存分配与回收(3) 之slab分配机制
- Java虚拟机学习 - 对象内存分配与回收
- Linux内核内存管理之SLAB内存管理算法(三) --slab对象的分配与释放
- 内存管理-SLAB(释放SLAB对象kmem_cache_free())
- Java虚拟机学习(7):对象内存分配与回收
- 9.《深入理解Java虚拟机》对象分配与回收策略
- Java虚拟机学习 - 对象内存分配与回收
- Linux内存管理之slab机制(分配对象)
- Java虚拟机学习(4):对象内存分配与回收
- 认识JVM(1)——对象分配&回收算法
- Java虚拟机学习 - 对象内存分配与回收
- 内存管理器(十七)kernel内存管理----slab设计与实现(分配对象)
- 各种垃圾回收器、对象分配内存原则、GC参数
- LINUX 2.6.37内存管理 SLAB分析之(3)SLAB对象分配与释放
- JVM之二——对象内存的分配和回收
- Java虚拟机学习 - 对象内存分配与回收
- Java对象的生命周期-内存分配、回收内存