Linux内存管理中的slab分配器
转载自: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分配器的更多相关文章
- linux内存源码分析 - SLAB分配器概述【转】
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 之前说了管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配给申请 ...
- linux内存源码分析 - SLAB分配器概述
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 之前说了管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配给申请 ...
- linux内存源码分析 - SLUB分配器概述
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ SLUB和SLAB的区别 首先为什么要说slub分配器,内核里小内存分配一共有三种,SLAB/SLUB/SLOB ...
- Linux内存管理 - slab分配器和kmalloc
本文目的在于分析Linux内存管理机制的slab分配器.内核版本为2.6.31.1. SLAB分配器 内核需要经常分配内存,我们在内核中最常用的分配内存的方式就是kmalloc了.前面讲过的伙伴系统只 ...
- Linux内核笔记——内存管理之slab分配器
内核版本:linux-2.6.11 内存区和内存对象 伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现. 如果我们需要请求具有连续物理地址 ...
- 【转帖】linux内存管理原理深入理解段式页式
linux内存管理原理深入理解段式页式 https://blog.csdn.net/h674174380/article/details/75453750 其实一直没弄明白 linux 到底是 段页式 ...
- Linux内存管理原理
本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...
- Linux内存管理原理【转】
转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...
- Windows内存管理和linux内存管理
windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...
随机推荐
- Python学习笔记(十)匿名函数
摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431843456 ...
- 「七天自制PHP框架」应用:Model外键链接
这里以行政区数据为例: 一级行政区数据范例: 二级行政区范例: 三级行政区范例: 在Model层建立三个Model class ProvinceModel extends Model{ public ...
- 【NOI2017】游戏 2-sat算法
[题目]LibreOJ [题意]n场游戏,有三种车ABC,给定长度为n的字符串,'a'表示不能选A,'b''c'同理,'x'表示不限,至多d个'x'.有m个限制(i,hi,j,hj)表示如果第i场选择 ...
- laravel 重定向路由带参数
转载: http://www.cnblogs.com/foreversun/p/5642176.html 举例: 路由: //任务列表页 $router->get('/taskDetail/{i ...
- wampserver 虚拟主机
转载:http://blog.csdn.net/knight_quan/article/details/51830683 1.背景: 在进行网站开发的时候,通常需要以http://localhost或 ...
- array_unique() 去重复
array_unique() 定义和用法 array_unique() 函数移除数组中的重复的值,并返回结果数组. 当几个数组元素的值相等时,只保留第一个元素,其他的元素被删除. 返回的数组中键名不变 ...
- 20、什么样的项目适合Web自动化测试
1.什么是Web自动化测试?概念:让程序代替人为自动验证Web项目功能的过程 2.什么Web项目适合做自动化测试 1.需求变动不频繁 2.项目周期长 3.项目需要回归测试 3.如阿进行Web自动化测试 ...
- Go语言 6 结构体、方法和接口
文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 结构体(struct)是由一系列具有相同类型或不同类 ...
- 使用Sass预定义一些常用的样式,非常方便
CSS预处理技术现在已经非常成熟,比较流行的有Less,Sass,Stylus,在开发过程中提升我们的工作效率,缩短开发时间,方便管理和维护代码,可以根据自己的喜好选择一款自己喜欢的工具开发,使用很接 ...
- flask插件系列之SQLAlchemy实用技巧
下面记录一下SQLAlchemy使用的技巧. 在多模块下定义models 如果由多个蓝图下读定义了model模块,在初始化的时候需要加载到上下文中. 当使用flask_Migrate迁移数据库的时候, ...