栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux内核学习笔记012 slab分配器

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux内核学习笔记012 slab分配器

一.slab核心思想

为每种对象类型创建一个内存缓存,每个内存缓存由多个大块组成,一个大块是一个或多个连续的物理页,每个大块包含多个对象。slab采用面向对象的思想,基于对象类型管理内存,每种对象被划分为一个类,比如进程描述符(task_struct)是一个类,每个进程描述符实现是一个对象。内存缓存组成结构如下:

二、编程接口

1)分配内存:void * kmalloc (size_t size,gfp_t flags);
2)重新分配内存:void *krealloc(const void *p, size_t new_size, gfp_t flags)
3)释放内存:void kfree ( const void * objp);

1)创建内存缓存:struct kmem_cache *kmem_cache_create(const char , size_t, size_t,unsigned long, void ()(void *));
2)指定的内存缓存分配对象:void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
3)释放对象:void kmem_cache_free(struct kmem_cache *, void *);
4)销毁内存缓存:void kmem_cache_destroy(struct kmem_cache *);

三、slab数据结构

• 每个内存缓存对应一个kmem_cache实例。
• 每个内存节点对应一个kmem_cache_node实例。
• kmem_cache实例的成员cpu_slab指向array_cache实例,每个处理器对应一个array_cach实例,称为数组缓存,用来缓存刚刚释放的对象,分配时首先从当前处理器的数据缓存分配,避免每次都要从slab分配,减少链表操作的锁操作,提高分配的速度。slab分配器数据结构源码分析如下:

四、高速缓存描述符数据结构:struct kmem_cache。

一个高速缓存中可以含有多个kmem_cache对应的高速缓存,就拿L1高速缓存来举例,一个L1高速缓存对应一个kmem_cache链表,这个链表中的任何一个kmem_cache类型的结构体均描述一个高速缓存,而这些高速缓存在L1 cache中各自占用着不同的区域。

内存缓存的主要数据结构如下:




每个slab由一个或者多个连续的物理页组成,页的阶数是kmem_cache.gfporder,如果阶数大于0,组成一个复合页。Slab被划分位多个对象,大多数情况下slab长度不是对象长度的整数倍。

空间对象链表:每个slab需要一个空闲对象链表,从而把所有的空闲对象连接起来,空闲对象链表是用数组来实现的,数组的元素个数是slab对象数量,数组存放空闲对象的索引。

五、每处理器数组缓存

内存缓存为每个处理器创建一个数组缓存(结构体array_cache)。释放对象时,把对象存放到当前处理器对应的数组缓存中;分配对象的时候,先从当前处理器的数组缓存分配对象,采用后进先出(LIFO)原则,可以提高性能。

刚释放的对象很可能还在处理器的缓存中,可以更好地利用处理器的缓存;减少对链表的操作;避免处理器之间互斥,减少自旋锁操作。
1.分配对象的时候,先从当前处理器的数组缓存分配对象,如果数组缓存是空的,那么批量分配对象以重新填充数组缓存,批量值就是数组缓存的成员batchcount。
2.释放对象的时候,如果数组缓存是满的,那么先把数组缓存中的对象地址批量归还给slab,批量值就是数组缓存的成员batchcount,然后把正在释放的对象存到数组缓存中。

六、回收内存

对于所有对象空间的slab,没有立即释放,而是放在空闲slab链表中。只有内存节点上
空闲对象的数量超过限制,才开始回收空闲slab,直到空闲对象的数量小于或等于限制。
节点n的空闲对象数量限制=(1+节点的处理器数量)*kmem_cache.batchcount+kmem_cache.num。
Slab分配器定期回收对象和空闲slab,实现方法是再每个处理器上向全局功罪队列添加一个延迟工作项,工作项的处理函数是cache_reap。
1.每个处理器每隔两秒钟对每个内存缓存执行回收节点n对应的远程节点数组缓存中的对象;如果过两面没有从当前处理器的数组缓存分配对象,那么回收数组缓存中的对象。
2.每个处理器每隔4秒钟对每个内存缓存执行,如果过两面没有从当共享数组缓存分配对象,那么回收共享数组缓存中的对象;如果过去4秒没有从空闲slab分配对象,那么回收空闲slab。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/756932.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号