转载自:http://edsionte.com/techblog/archives/4019

Linux内核中基于伙伴算法实现的分区页框分配器适合大块内存的请求,它所分配的内存区是以页框为基本单位的。对于内核中小块连续内存的请求,比 如说几个字节或者几百个字节,如果依然分配一个页框来来满足该请求,那么这很明显就是一种浪费,即产生内部碎片(internal fragmentation)

为了解决小块内存的分配,Linux内核基于Solaris 2.4中的slab分配算法实现了自己的slab分配器。除此之外,slab分配器另一个主要功能是作为一个高速缓存,它用来存储内核中那些经常分配并释放的对象。

1.slab分配器的基本原理

slab分配器中用到了对象这个概念,所谓对象就是内核中的数据结构以及对该数据结构进行创建和撤销的操作。它的基本思想是将内核中经常使用的对象 放到高速缓存中,并且由系统保持为初始的可利用状态。比如进程描述符,内核中会频繁对此数据进行申请和释放。当一个新进程创建时,内核会直接从slab分 配器的高速缓存中获取一个已经初始化了的对象;当进程结束时,该结构所占的页框并不被释放,而是重新返回slab分配器中。如果没有基于对象的slab分 配器,内核将花费更多的时间去分配、初始化以及释放一个对象。

slab分配器有以下三个基本目标:

1.减少伙伴算法在分配小块连续内存时所产生的内部碎片;

2.将频繁使用的对象缓存起来,减少分配、初始化和释放对象的时间开销。

3.通过着色技术调整对象以更好的使用硬件高速缓存;

2.slab分配器的结构

slab分配器为每种对象分配一个高速缓存,这个缓存可以看做是同类型对象的一种储备。每个高速缓存所占的内存区又被划分多个slab,每个 slab是由一个或多个连续的页框组成。每个页框中包含若干个对象,既有已经分配的对象,也包含空闲的对象。slab分配器的大致组成图如下:

每个高速缓存通过kmem_cache结构来描述,这个结构中包含了对当前高速缓存各种属性信息的描述。所有的高速缓存通过双链表组织在一起,形成 高速缓存链表cache_chain。每个kmem_cache结构中并不包含对具体slab的描述,而是通过kmem_list3结构组织各个 slab。该结构的定义如下:

1 struct kmem_list3 {
2         struct list_head slabs_partial;
3         struct list_head slabs_full;
4         struct list_head slabs_free;
5         unsigned long free_objects;
6         unsigned int free_limit;
7         unsigned int colour_next;
8         spinlock_t list_lock;
9         struct array_cache *shared;
10         struct array_cache **alien;
11         unsigned long next_reap;
12         int free_touched;
13 };

可以看到,该结构将当前缓存中的所有slab分为三个集合:空闲对象的slab链表slabs_free,非空闲对象的slab链表 slabs_full以及部分空闲对象的slab链表slabs_partial。每个slab有相应的slab描述符,即slab结构,它的定义如下:

1 struct slab {
2         struct list_head list;
3         unsigned long colouroff;
4         void *s_mem;
5         unsigned int inuse;
6         kmem_bufctl_t free;
7         unsigned short nodeid;
8 };

slab描述符中的list字段标明了当前slab处于三个slab链表的其中一个。我们将上述的slab分配器进行细化,可以得到下面的结构图:

3.高速缓存的分类

slab高速缓存分为两大类,普通高速缓存和专用高速缓存。普通高速缓存并不针对内核中特定的对象,它首先会为kmem_cache结构本身提供高 速缓存,这类缓存保存在cache_cache变量中,该变量即代表的是cache_chain链表中的第一个元素;另一方面,它为内核提供了一种通用高 速缓存。专用高速缓存是根据内核所需,通过指定具体的对象而创建。

3.1 普通高速缓存

slab分配器中kmem_cache是用来描述高速缓存的结构,因此它本身也需要slab分配器对其进行高速缓存。cache_cache变量保存着对高速缓存描述符的高速缓存。

1 static struct kmem_cache cache_cache = {
2         .batchcount = 1,
3         .limit = BOOT_CPUCACHE_ENTRIES,
4         .shared = 1,
5         .buffer_size = sizeof(struct kmem_cache),
6         .name = "kmem_cache",
7 };

slab分配器所提供的小块连续内存的分配是通过通用高速缓存实现的。通用高速缓存所提供的对象具有几何分布的大小,范围为32到131072字节。内核中提供了kmalloc()和kfree()两个接口分别进行内存的申请和释放。

3.2 专用高速缓存

内核为专用高速缓存的申请和释放提供了一套完整的接口,根据所传入的参数为具体的对象分配slab缓存。

高速缓存的申请和释放

kmem_cache_create()用于对一个指定的对象创建高速缓存。它从cache_cache普通高速缓存中为新的专有缓存分配一个高速 缓存描述符,并把这个描述符插入到高速缓存描述符形成的cache_chain链表中。kmem_cache_destory()用于撤销一个高速缓存, 并将它从cache_chain链表上删除。

slab的申请和释放

kmem_cache_alloc()在其参数所指定的高速缓存中分配一个slab。相反,kmem_cache_free()在其参数所指定的高速缓存中释放一个slab。

Linux内存管理中的slab分配器的更多相关文章

  1. linux内存源码分析 - SLAB分配器概述【转】

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 之前说了管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配给申请 ...

  2. linux内存源码分析 - SLAB分配器概述

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 之前说了管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配给申请 ...

  3. linux内存源码分析 - SLUB分配器概述

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ SLUB和SLAB的区别 首先为什么要说slub分配器,内核里小内存分配一共有三种,SLAB/SLUB/SLOB ...

  4. Linux内存管理 - slab分配器和kmalloc

    本文目的在于分析Linux内存管理机制的slab分配器.内核版本为2.6.31.1. SLAB分配器 内核需要经常分配内存,我们在内核中最常用的分配内存的方式就是kmalloc了.前面讲过的伙伴系统只 ...

  5. Linux内核笔记——内存管理之slab分配器

    内核版本:linux-2.6.11 内存区和内存对象 伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现. 如果我们需要请求具有连续物理地址 ...

  6. 【转帖】linux内存管理原理深入理解段式页式

    linux内存管理原理深入理解段式页式 https://blog.csdn.net/h674174380/article/details/75453750 其实一直没弄明白 linux 到底是 段页式 ...

  7. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

  8. Linux内存管理原理【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

  9. Windows内存管理和linux内存管理

    windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

随机推荐

  1. springsecurity 表达式一览

    表达式 描述 hasRole([role]) 当前用户是否拥有指定角色. hasAnyRole([role1,role2]) 多个角色是一个以逗号进行分隔的字符串.如果当前用户拥有指定角色中的任意一个 ...

  2. spring boot 2.0.3+spring cloud (Finchley)9、 安全组件Spring Boot Security

    官方文档 一.Spring Security介绍 Spring Security是Spring Resource社区的一个安全组件,Spring Security为JavaEE企业级开发提供了全面的安 ...

  3. Linux centos7下设置Tomcat开机自启动

    1,centos7 使用 systemctl 替换了 service命令 参考:redhat文档: https://access.redhat.com/documentation/en-US/Red_ ...

  4. NOIP模拟赛9

    T1U3348 A2-回文数 https://www.luogu.org/problem/show?pid=U3348 考场上钻了牛角尖了,然后0分 #include<cstdio> #i ...

  5. 「LibreOJ β Round #4」框架

    https://loj.ac/problem/527 题目描述 有一个n×m的矩形框架,但其中有些边被删除了.qmqmqm想知道剩余部分中还有多少完整的正方形.只有当一个正方形的每一条边均被保留下来, ...

  6. 非法字符:"\ufeff"

    Eclipse项目导入IDEA可能遇到这样的问题 ,原因就是: 带BOM的UTF-8」和「无BOM的UTF-8」 方法一.用Notepad++把文件转成无BOM的UTF-8 另存为,替换原来的文件 方 ...

  7. CSS进阶知识

    html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; } 该属性的作用是 ...

  8. 【BZOJ4870】组合数问题(计数DP,快速幂)

    题意: 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 思路:From http://blog.csdn.net/qq_33229466/artic ...

  9. select多选框

    select多选框 效果: 代码: <HTML> <HEAD> <TITLE>选择下拉菜单</TITLE> <meta http-equiv=&q ...

  10. js刷题:leecode 25

    原题:https://leetcode.com/problems/reverse-nodes-in-k-group/ 题意就是给你一个有序链表.如1->2->3->4->5,还 ...