分类:
2012-05-28 12:43:34
Slab分配器把对象分组放进高速缓存(cache),以避免重复初始化对象。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。
对象高速缓存的组织如下图所示,高速缓存的内存区被划分为多个slab,每个slab由一个或多个连续的页框组成,这些页框中既包含已分配的对象,也包含空闲的对象。
FQL同学问了个问题,说为什么高速缓存中需要slab中间层,直接cache中包含对象不就OK么? 我初次看这个图的时候也考虑过这个问题,但没有深入分析,昨天分析了一下,下面的内容应该能回答这个问题。
1. 高速缓存是一系列对象的结合,用于减少每次申请对象内存构造(初始化)对象的时间。
2. 高速缓存的大小随内核使用对象的频度变化,即高速缓存的大小是可以动态变化的,从kmem_cache_create的参数就可以看出,只需指明对象的大小,不指定高速缓存的总大小。当需要很多对象时,可增加高速缓存的大小;当对象不再频繁使用时,可以回收高速缓存的部分空间。
3. 假如没有slab层,高速缓存直接由多个页组成。当内核需要申请一个新的对象时,由于对象的申请和释放是随机的,定位一个空闲对象会遍历各个页找出一个空闲对象。同时,当高速缓存需要释放一些页面时,需要先定位哪些页面是完全空闲的。如果没有任何的辅助信息,上面两个过程效率是非常低的,可通过为页增加额外的描述信息来提高效率,比如页上对象的个数及分配情况(全部空闲,全部分配,还是部分分配)等。
4. Slab管理多个页面,slab被划分为多种类型(全部分配的slab,部分分配的slab以及空闲的slab),并包含一些描述信息包括slab中第一个对象的地址,非空闲对象个数,下一个空闲对象下标等。这些描述信息与3中需要为页增加的描述信息基本相同。
5. 从以上4点可以看出,增加slab中间层其实是在时间和空间上的折中方案。