Linux内核笔记——内存管理之slab分配器
内核版本:linux-2.6.11
内存区和内存对象
伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现。
如果我们需要请求具有连续物理地址和任意长度的内存单元序列时,即不定大小的内存区时,则需要在伙伴系统之上提供一层更细粒度的管理方案。
Linux在分配内存的时候,会将这部分内存初始化成一定的类型,即内存对象,例如信号、进程描述符、文件描述符等等,在释放的时候,会进行析构。
然而进行初始化和析构占用的时间已然超出了分配这部分内存的时间,于是,需要一个机制能够省略内存初始化和内存析构的时间,这对提升内存从分配到使用再到释放这一系列处理过程的性能有着莫大帮助。
slab分配器
出于这两种需求,slab出现了。
slab分配器最早是由Jeff Bonwick引进Solaris 5.4内核中的,如今各主流Unix-like系统都在使用。
它充当了伙伴系统和内存区分配接口之间的中间件。
举一个完整的例子,假设之前没有任何可用高速缓存的情况下,slab分配器接收到第一个内存分配请求时,首先会调用伙伴系统来分配足够大小的页框,然后按照一定规则初始化这部分内存,返回。内存释放时,slab分配器不会马上析构这部分内存,而是标记为可用,下一次的内存分配请求如果类型相同,那么直接使用可用的未析构的那块内存区,这样一来,高速缓存中会留有相同类型内存区的可用链表,只要链表不为空,那么该类型的内存区分配请求将会跳过初始化这一步直接得到满足。
所以说整个slab分配器的核心就是缓存(硬件高速缓存),是一种用空间换时间的聪明机制。
高速缓存
讲到这里,不得不补充一下高速缓存这个东西。
由于多级高速缓存之间的一致性是由硬件实现的,因此对于Linux而言,CPU片内只有一个逻辑的高速缓存,单位为行,一般由几十个连续的字节组成,同时,片内存在一个高速缓存控制器,里面保存了从高速缓存行到主存单元的映射表,由此判断访问内存时是否命中高速缓存。
Linux在系统初始化的时候调用函数kmem_cache_init()和函数kmem_cache_sizes_init()初始化了一系列高速缓存,并创建描述符以供slab分配器使用。
slab本身是存在于高速缓存以及对应的页框里的,由高速缓存控制器控制这里的高速缓存跟主存保持一致。
核心处理流程
- 为新的slab分配页框
kmem_getpages()调用伙伴系统的alloc_pages()函数接口,返回首个页描述符指针。 - 给高速缓存分配slab
cache_grow给高速缓存分配一个新的slab,同时调用cache_init_objs(),该函数主要代码如下
static void cache_init_objs(struct kmem_cache *cachep, struct page *page)
{
for (i = 0; i < cachep->num; i++) {
void *objp = index_to_obj(cachep, page, i);
if (cachep->ctor)
cachep->ctor(objp);
set_obj_status(page, i, OBJECT_FREE);
set_free_obj(page, i, i);
}
}
第一个参数为指定高速缓存的描述符指针,第二个参数为上一步调用伙伴系统分配的首个页框的描述符指针。
用途是将这个新的slab中的所有对象的构造函数设为该高速缓存中注册的构造函数,且将他们全部设为空闲。
由这里也可以看出,对象类型是跟高速缓存绑定的,即一个高速缓存描述符对应的这一块硬件高速缓存中的所有slab中的所有对象都是同一种类型的。- 分配slab对象
假设上一步初始化了一个服务于A类型对象的slab,此时,我们就拥有了一组A类型的空闲对象虚位以待。
当接到内存区分配请求时,通过指定拥有不同构造函数的高速缓存描述符来调用kmem_cache_alloc(cachep, flags)就可以获得相应的空闲内存对象指针。
- 为新的slab分配页框
总结一下
首先,系统初始化了两组高速缓存,第一组包括各个指定类型(task_struct、mm_struct、singal等等)的高速缓存,第二组则是一系列2的幂字节大小的通用对象(范围从32-131072)的高速缓存,内核其他模块进行内存区分配请求时,指定好自己需要的内存类型所对应的高速缓存,例如,新建进程时就需要指定第一组中的task_struct对应高速缓存,kmalloc函数则是指定第二组中的高速缓存,slab分配器会取得指定高速缓存中的一个空闲内存对象返回给请求模块。
slab分配器在做分配和释放内存对象的工作时,会尽量减少构造新对象和析构旧对象以实现这个空间换时间的算法。
PS: 有什么问题,请各位一定指出,万分感谢。
Linux内核笔记——内存管理之slab分配器的更多相关文章
- Linux内核笔记--内存管理之用户态进程内存分配
内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...
- Linux内核笔记——内存管理之块内存分配
内核版本:linux-2.6.11 伙伴系统 伙伴系统是linux用于满足对不同大小块物理内存分配和释放请求的解决方案. 内存管理区 linux将物理内存分成三个内存管理区,分别为ZONE_DMA Z ...
- 24小时学通Linux内核之内存管理方式
昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今天将会讲诉Linux如何追踪和管理用户空间进程的可用内 ...
- Linux内核之内存管理
Linux内核之内存管理 Linux利用的是分段+分页单元把逻辑地址转换为物理地址; RAM的某些部分永久地分配给内核, 并用来存放内核代码以及静态内核数据结构; RAM的其余部分称动态内存(dyna ...
- Linux内存管理 (5)slab分配器
专题:Linux内存管理专题 关键词:slab/slub/slob.slab描述符.kmalloc.本地/共享对象缓冲池.slabs_partial/slabs_full/slabs_free.ava ...
- 把握linux内核设计思想(十二):内存管理之slab分配器
[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流.请勿用于商业用途] 上一节最后说到对于小内存区的请求,假设採用伙伴系统来进行分配,则会在页内产生非 ...
- Linux内存管理之slab分配器
slab分配器是什么? 参考:http://blog.csdn.net/vanbreaker/article/details/7664296 slab分配器是Linux内存管理中非常重要和复杂的一部分 ...
- 内存管理之slab分配器
基本思想 与传统的内存管理模式相比, slab 缓存分配器提供了很多优点.首先,内核通常依赖于对小对象的分配,它们会在系统生命周期内进行无数次分配.slab 缓存分配器通过对类似大小的对象进行缓存而提 ...
- 深入理解Linux内核-内存管理
内核如果给自己分配动态内存 动态内存:RAM的某些部分被永久打分配给内核,用来存放内核代码以及静态内核数据结构:剩余的部分被称为动态内存 连续物理内存区管理: 页框管理:1.页大小的选择,通常情况下主 ...
随机推荐
- C和指针 第十六章 标准函数库
字符串转换: long int strtol(char const *string, char **unused, int base); 将字符串转换为数值形式,遇到非法字符停止,如果stop不是NU ...
- 反编译apk
一.反编译Apk得到Java源代码 首先要下载两个工具:dex2jar和JD-GUI 前者是将apk中的classes.dex转化成Jar文件,而JD-GUI是一个反编译工具,可以直接查看Jar包的源 ...
- tab 切换写法
<script> var oUL = document.getElementById('aboutTab-ul'); var oLi = oUL.getElem ...
- python3 TypeError: 'str' does not support the buffer interface in python
http://stackoverflow.com/questions/38714936/typeerror-str-does-not-support-the-buffer-interface-in-p ...
- EndNote(三)之中文引文导入方式
上一篇文章讲了Web of Science,PubMed的引文如何导入到EndNote中.这次,写一下常用的中文文献查找网站的引文如何导入EndNote. 本人常用的中文文献查找网站,主要是知网(CN ...
- 打印IP 来源
<% String userAgent = request.getHeader("User-Agent"); if (userAgent != null && ...
- 高性能MySQL(四):schema陷阱
一.schema陷阱 二.缓存表和汇总表 三.范式和反范式
- Angular2 Http
1. 使用Http 绝大部分应用程序都会和后台服务打交道,Http是浏览器和服务器之间通讯的主要协议,通过Http调用来访问远程服务器上相应的 Web API. HttpModule 并不是 Angu ...
- iOS 手势识别器(UIGestureRecognizer)
UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势. UIGestureRecognizer的子类有: UITapGestureRecogni ...
- 二维码跳转不同的 app store
说道二维码 之前是用来跳转app store 然后在就是出来的 扫码付款什么的 用的很平常,其实里面也很简单 自己刚开始接触的时候 同事说要做一个二维码下载 应用 => 我=懵逼 ...