原理简介:Linux内存分配机制:伙伴系统buddy system和slab分配器

本文参考兰新宇大佬的文章内存分配系列文章。

buddy system

当系统内核初始化完毕后,使用页分配器管理物理页,Linux 使用的页分配器是伙伴分配器。

连续的物理页称为页块(page block)。 2 n 2^n 2n 个连续页称为 n 阶页块。

每阶有一个 freelist 维护该阶的空页块。

// include/linux/mmzone.h


struct zone{
 ...
    /* free areas of different sizes */
    struct free_area    free_area[MAX_ORDER];
 ...
} zone;

在这里插入图片描述

分配

当需要分配一段内存时,系统会寻找合适大小的内存块。如果找到了一个恰好大小的内存块,则直接分配给请求的程序;如果没有找到,系统会向上搜索直到找到一个更大的内存块,然后将其切分成合适大小的块,并将其中一个分配给请求的程序,将剩余的部分继续保留在内存池中。

申请 128 字节的内存:

请添加图片描述

查找合适块:首先查看 size 为 128 字节的 free list,但没有空闲块。再看 256 字节的 free list,还是没有,再看 512 字节的 free list,找到一个空闲的内存块 A’。

分割内存块:将 A’划分为 256 字节的 E 和 E’,再将内存块 E 划分成 128 字节的 F 和 F’,内存块 F 即是们需要的内存。之后,在此过程中产生的 E’和 F’将分别被挂接到 size 为 256 字节和 128 字节的 free list 上,位图中 bits 的值也会相应变化。

在这里插入图片描述

释放

当程序释放内存时,系统会将这块内存标记为空闲状态,并尝试将其与相邻的空闲块合并,以形成更大的空闲块,方便后续的分配。

释放 128 字节的内存块 C,由于 C 相邻的两个内存块都不是空闲状态,因此不能合并,之后 C 也将被挂接到 size 为 128 字节的 free list 上。

在这里插入图片描述

再释放释放 64 字节的内存块 D:

分配器根据 bitmap 可知,右侧的 D’也是空闲的,且 D 和 D’的大小相同,因此 D 和 D’将合并。合并后的空闲内存块 C’为 128 字节,应该被添加到 size 为 128 字节的 free list 上,但是因为左侧的 C 也是空闲的,且 C 和 C’的大小相同,因此 C 和 C’进一步合并形成 B’,合并后的空闲内存块将被挂接到 size 为 256 字节的 free list 上。

在这里插入图片描述

优缺点

优点:

根据需要分配内存的大小直接可以计算出当前这次分配应该从哪个 order 的 free list 开始找空闲的内存块,因此分配的效率比 boot memory 的线性扫描 bitmap 要快很多。

缺点:

  1. 释放 page 的时候调用方必须记住之前该 page 分配的 order,然后释放从该 page 开始的 2 o r d e r 2^{order} 2order 个 page,对于调用者来说不方便
  2. 每次分配必须是 2 o r d e r 2^{order} 2order 个 page,如果需要的内存大小不是 2 的阶,会造成内部碎片。

Linux 为了解决 buddy system 造成的内部碎片问题,引入 slab 分配器处理小粒度的内存分配。

slab 分配器

Linux 中的 buddy 分配器是以 page frame 为最小粒度的,而有很多现实的应用以内核 objects 的大小来申请和释放内存的,这些内核 objects 的大小通常从几十字节到几百字节不等,远远小于一个 page 的大小。

结构

slab 分配器用于分配小块内存。它从内存管理模块申请一整块页,然后划分成多个小块的存储池,用队列来维护这些小块的状态。

在 slab 分配器中,每一类 objects 拥有一个"cache"(比如 inode_cache, dentry_cache)。每分配一个 object,都从包含若干空闲的同类 objects 的区域获取,释放时也直接回到这个区域,这样可以缓存和复用相同的 objects,加快分配和释放的速度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

cache 的内存从 buddy allocator 获得。slab 层直接面向程序的分配需求,相当于是前端,而 buddy system 则成为 slab 分配器的后端

每个 cache 的内存在物理上是连续的。一个 cache 分成若干个 slabs,同一 cache 中的 slabs 都存储相同的 objects。
在这里插入图片描述

Slab 分配器是一种内存分配算法,常用于操作系统中管理内核内存。它的主要优点和缺点如下:

优缺点

优点:

  1. 降低内存碎片化:可以提供小块内存的分配支持,提高内存利用率。
  2. 减少内存分配和释放的开销:Slab 分配器通过重复使用预分配的内存块,使得内存的申请和释放不必每次需要 buddy system 介入,提高了分配和释放的效率

缺点:

  1. 设计实现比较复杂
  2. 建立 slab 分配器的数据结构就需要大量内存,可以使用经过优化的 slub 分配器

参考

Linux Memory Management - The Buddy Allocator (carcano.ch)

The Buddy System Algorithm - Linux Kernel Reference (halolinux.us)

linux/mm/mmzone.c at v2.6.39 · torvalds/linux (github.com)

内存分配[二] - Buddy系统的原理 - 知乎 (zhihu.com)

内存分配[四] - Linux中的Slab(1) - 知乎 (zhihu.com)

Linux内存管理-伙伴系统分析 | Sherlock’s blog (wangzhou.github.io)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值