内核版本: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)就可以获得相应的空闲内存对象指针。

总结一下

首先,系统初始化了两组高速缓存,第一组包括各个指定类型(task_struct、mm_struct、singal等等)的高速缓存,第二组则是一系列2的幂字节大小的通用对象(范围从32-131072)的高速缓存,内核其他模块进行内存区分配请求时,指定好自己需要的内存类型所对应的高速缓存,例如,新建进程时就需要指定第一组中的task_struct对应高速缓存,kmalloc函数则是指定第二组中的高速缓存,slab分配器会取得指定高速缓存中的一个空闲内存对象返回给请求模块。

slab分配器在做分配和释放内存对象的工作时,会尽量减少构造新对象和析构旧对象以实现这个空间换时间的算法。


PS: 有什么问题,请各位一定指出,万分感谢。

Linux内核笔记——内存管理之slab分配器的更多相关文章

  1. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  2. Linux内核笔记——内存管理之块内存分配

    内核版本:linux-2.6.11 伙伴系统 伙伴系统是linux用于满足对不同大小块物理内存分配和释放请求的解决方案. 内存管理区 linux将物理内存分成三个内存管理区,分别为ZONE_DMA Z ...

  3. 24小时学通Linux内核之内存管理方式

    昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今天将会讲诉Linux如何追踪和管理用户空间进程的可用内 ...

  4. Linux内核之内存管理

    Linux内核之内存管理 Linux利用的是分段+分页单元把逻辑地址转换为物理地址; RAM的某些部分永久地分配给内核, 并用来存放内核代码以及静态内核数据结构; RAM的其余部分称动态内存(dyna ...

  5. Linux内存管理 (5)slab分配器

    专题:Linux内存管理专题 关键词:slab/slub/slob.slab描述符.kmalloc.本地/共享对象缓冲池.slabs_partial/slabs_full/slabs_free.ava ...

  6. 把握linux内核设计思想(十二):内存管理之slab分配器

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流.请勿用于商业用途] 上一节最后说到对于小内存区的请求,假设採用伙伴系统来进行分配,则会在页内产生非 ...

  7. Linux内存管理之slab分配器

    slab分配器是什么? 参考:http://blog.csdn.net/vanbreaker/article/details/7664296 slab分配器是Linux内存管理中非常重要和复杂的一部分 ...

  8. 内存管理之slab分配器

    基本思想 与传统的内存管理模式相比, slab 缓存分配器提供了很多优点.首先,内核通常依赖于对小对象的分配,它们会在系统生命周期内进行无数次分配.slab 缓存分配器通过对类似大小的对象进行缓存而提 ...

  9. 深入理解Linux内核-内存管理

    内核如果给自己分配动态内存 动态内存:RAM的某些部分被永久打分配给内核,用来存放内核代码以及静态内核数据结构:剩余的部分被称为动态内存 连续物理内存区管理: 页框管理:1.页大小的选择,通常情况下主 ...

随机推荐

  1. CSS实现可变行数垂直居中

    <html> <head> <style> .vcenter { position: relative; height: 100%; width:50px; } . ...

  2. mybatis逆向工程生成JavaBean、dao、mapper generatorSqlmapCustom

    import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator ...

  3. java基础 常用组件

    几个常用组件: 在图形用户界面编程中,我们常常会提供用户登陆界面,比如登陆到会员管理系统,登陆到工资管理系统,仓库管理系统等,如下图我们就会用到: 1. 文本框(JTextField) 2. 密码框( ...

  4. js之认识闭包

    本文采用5W1H分析法来看一下闭包. 一.why-----从为什么要引入闭包先来了解一下闭包. 讨论为什么要引入闭包就要先讨论一下js中的作用域链及垃圾回收机制. 熟悉js语言的人都知道js中有作用域 ...

  5. Eclipse使用Maven tomcat:run命令启动web项目时修改默认端口

  6. 【CQOI2011】动态逆序对 BZOJ3295

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  7. 《jQuery知识点总结》(二)

    dom css 操作html(n)                n为空则取值相当于JS的innerHTML填写n为赋值val(n)                n为空则取值相当于JS的value填 ...

  8. 一段SQL

    如何将会计分录流水合并成会计分录,环境oracle 11g,代码如下: 表: CREATE TABLE "DEMO_VCH" ("SET_NO" BYTE), ...

  9. 33个超级有用必须要收藏的PHP代码样例

    作为一个正常的程序员,会好几种语言是十分正常的,相信大部分程序员也都会编写几句PHP程序,如果是WEB程序员,PHP一定是必备的,即使你没用开发过大型软件项目,也一定多少了解它的语法. 在PHP的流行 ...

  10. 在CentOS 7 中 安装 VSFTP

    在线安装:yum install -y vsftpd 使用yum 进行卸载:yum -y remove vsftpd 编辑配置:vi /etc/vsftpd/vsftpd.conf 查看FTP进程是否 ...