Linux内核——伙伴系统跟slab缓存

时间:2021-10-21 23:36:34
Linux内核——伙伴系统和slab缓存

    伙伴系统

    使用场景:内核中很多时候要求分配连续页,为快速检测内存中的连续区域,内核采用了一种技术:伙伴系统。

    原理:系统中的空闲内存总是两两分组,每组中的两个内存块称作伙伴。伙伴的分配可以是彼此独立的。但如果两个小伙伴都是空闲的,内核将其合并为一个更大的内存块,作为下一层次上某个内存块的伙伴。如下图给出了一对伙伴,初始大小均为8页。

    Linux内核——伙伴系统跟slab缓存

      内核对所有大小相同的小伙伴,都放置到统一列表中管理。如果系统现在需要8个页帧,则将16个页帧组成的块拆分为两个伙伴。其中一块用于满足应用程序的请求,而剩余的8个页帧则放置到对应8页大小内存块的列表中。

    如果下一个请求只需要2个连续页帧,则由8页组成的块分裂成2个伙伴,每个包含4个页帧。其中一块放置回伙伴列表中,而另一个再次分裂成2个伙伴,每个包含2页。其中一个回到伙伴系统,另一个则传递给应用程序。

    在应用程序释放内存时,内核可以直接检查地址,来判断是否创建一组伙伴,并合并为一个更大的内存块放回到伙伴列表中,这刚好是内存块分裂的逆过程,提高了较大内存块的可用性。

    slab缓存

    适用场景:内核本身经常需要比完整页帧小的多的内存块。

    原理:在伙伴系统基础上自行定义额外的内存管理层,将伙伴系统提供的页划分为更小的部分。

    方法1:对频繁使用的对象,内核定义了只包含了所需类型对象实例的缓存。每次需要某种对象时,可以从对应的缓存快速分配(使用后释放到缓存)。slab缓存自动维护与伙伴系统的交互,在缓存用尽时会请求新的页帧。

    方法2:对通常情况下小内存块的分配,内核针对不同大小的对象定义了一组slab缓存,可以像用户空间编程一样,用相同的函数访问这些缓存。不同之处是这些函数都增加了前缀k,表明是与内核相关联的:kmalloc和kfree。

           Linux内核——伙伴系统跟slab缓存