HelloOs总结之内存管理(下)

HelloOs总结之内存管理(下)

      • 4.3.2 Slab系统


 

4.3.2 Slab系统

   如上面所述,伙伴系统作为一个基础的内存分配算法,其很好的解决了外部碎片的问题,但是如果用户要求分配很小的内存空间,比如说几十个字节,那么如果直接使用buddy系统分配一个页框(也就是最小块4KB),那么会有大量的内部碎片。这时候就引出了另一种分配方案:Slab系统。
   所谓Slab系统,通俗地讲,就是专门为某一模块预先申请一定数量的内存备用,当这个模块想要使用内存的时候,就不需要从系统中分配内存了(从系统中申请内存比较耗时),而是直接从预先申请的内存中拿出一部分来使用。从某种角度来说,Slab系统就是一种缓存机制。
   对于Slab系统来说,其还有一个优点。就是其是基于对象进行管理的(这里所说的对象可以理解为内核的一些数据结构,如文件描述符、进程描述符等等,这些对象一般都具有固定的大小,而且大小一般都是几十到几百个字节)。相同类型的对象归为一类,每当要申请这样一个对象时,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,这样可以更快速的分配给下一个申请的对象,避免了重复的初始化过程。
   ok,简单总结一下Slab系统的优点:
   (1)、可以实现更小粒度的分配。
   (2)、使用缓存机制,基于对象进行管理,可以提高内核申请、释放相同对象的效率。

   HelloOs中虽然实现了Slab系统,但最终没在其他模块中用到这个系统,所以从某种程度上来说,HelloOs中的Slab系统是一个相对独立的模块(当然,其需要使用伙伴系统)。下面简单介绍Slab系统的实现过程。
   从某种程度上说,Slab系统的总体实现和伙伴系统很相似(尤其是其初始化时对其组织的方式)。不同的是,伙伴系统是管理一大块原始的内存区域,而Slab系统作为缓存机制,管理的是从伙伴系统中事先分配好的内存区域(也就是一般Slab系统是以伙伴系统为基础的)。
   同时,一般来说,我们设计Slab系统时,会统一管理不同档次的内存大小。如在HelloOs中是以32字节为一个档次,即32B、64B、96B、128B、 … 4K大小,总共128个档次。如果需要向Slab系统申请一个大小为60字节的对象时,会自动对齐到64B,所以会从64B档次的对象池中分配一个对象。
   在HelloOs中用struct kmem_cache来描述一个slab档次,其具体成员如下图4.13所示。

HelloOs总结之内存管理(下)_第1张图片
图4.13 keme_cache 结构体示意图

   对于slab系统来说,对其管理主要有如下几个步骤,如下图4.14所示。

HelloOs总结之内存管理(下)_第2张图片
图4.14 Slab使用流程

   下面简要分析以上四个步骤:
   (1)、初始化阶段。这个阶段使用kmem_cache_create函数从伙伴系统中获得所管理的内存空间,并将其串在一起(按照kmem_cache档次的大小)。注意,这个函数只是针对一个slab档次,也就是一个kmem_cache 进行初始化,所以对于HelloOs来说,其需要调用这个函数初始化127次。
   哦,还需要注意一点,给kmem_cache分配内存空间(这里的内存空间就是利用伙伴系统分配页框)时,一般是按照一定的规则进行分配,HelloOs中使用的规则是:kme_cache的档次大小size小于等于分配页框的10%(即分配的页框至少可以分配10次)。HelloOs中使用find_right_order这个函数来实现这个功能。
   一个keme_cache初始化之后,其示意图如下图4.15所示。

HelloOs总结之内存管理(下)_第3张图片
图4.15 slab 初始化后示意图

   (2)、分配阶段。上层系统调用kmem_cache_alloc 从相应的kmem_cache中分配一个对象块给上层。这里对象块就是kmem_cache档次的大小。
   (3)、回收阶段。上层调用kmem_cache_free释放对象块的大小。这里Slab系统并不真正释放对象块的内存空间,而是把对象块回收起来,以便下次分配。
   (4)、销毁阶段。这个阶段和初始化阶段相对应,Slab系统把所占用的内存空间释放,归还给伙伴系统。

   以上就是Slab系统的一些内容,当然,真正广泛应用的Slab系统(如linux中),slab系统实现要复杂的多,但原理大同小异。这里仅是抛砖引玉,想深入了解的,可以查阅相关资料。这里可以推荐几个网址:
(1)、https://blog.csdn.net/qq_22238021/article/details/80214759
(2)、https://blog.csdn.net/zhouwei1221q/article/details/48242535
(3)、https://juejin.im/post/6844904083573178382#heading-12
(4)、https://zhuanlan.zhihu.com/p/61457076


 
好了到这儿,内存管理就算总结完了。
看个视频,休息一会,整理心情,继续出发。

你可能感兴趣的:(HelloOs总结)