news 2026/5/1 5:48:08

Buddy分配器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Buddy分配器

Buddy分配器

1. 内核在基本的伙伴分配器基础改进扩展

支持内存节点和区域,称为分区的伙伴分配器(zoned buddy allocator)。
为了预防内存碎片,把物理页框通过移动性分组。
针对分配单页做了性能优化,为了减少处理器锁的竞争,在内存区域增加了1个每处理器页集合。

2. 分区的伙伴分配器源码分析

2.1 数据结构

#defineMAX_ORDER11// MAX_ORDER是最大阶数,实际上最大可分配的是最大阶数加1,默认值是11,意味着伙伴分配器一次最多可以分配2^10页。structfree_area{structlist_headfree_list[MIGRATE_TYPES];// 不同类型的空闲区域unsignedlongnr_free;};structzone{/* ... */structfree_areafree_area[MAX_ORDER];/* ... */};

2.2 根据分配标志获取首选区域类型

内核使用GFP_ZONE_TABLE定义了标志组合到区域类型的映射表。其中GFP_ZONES_SHIFT是区域类型占用的位数。GFP_ZONE_TABLE把每种标志组合映射到32位整数的某个位置,偏移是(标志组合 * 区域类型位数),从这个偏移开始的GFP_ZONES_SHIFT个二进制位存放区域类型。

3. 备用区域列表 (Zonelist)

借用必须遵守规则:
一个内存节点的某个区域类型可以从另一个内存节点的相同区域类型借用物理页,比如节点0的普通区域可以从节点1的普通区域借用物理页。
高区域类型可以从低区域类型借用物理页,比如普通区域可以从DMA区域借用物理页。
低区域类型不能从高区域类型借用物理页,比如DMA区域不能从普通区域借用物理页。

包含所有内存节点的备用区域列表有两种排序方法:

  1. 节点优先顺序:先根据节点距离从小到大排序,然后在每个节点里面根据区域类型从高到低排序。优点是优先选择距离近的内存,缺点是在高区域耗尽以后使用低区域。
  2. 区域优先顺序:先根据区域类型从高到低排序,然后在每个区域类型里面根据节点距离从小到大排序。优点是减少低区域耗尽的几率,缺点是不能保证优先选择距离近的内存。

默认的排序方法就是自动选择最优的排序方法:比如是64位系统,因为需要DMA和DMA32区域的备用相对少,所以选择节点优先顺序;如果是32位系统,选择区域优先顺序。

4. 区域水位 (Watermarks)

数据结构如下:

enumzone_watermarks{WMARK_MIN,WMARK_LOW,WMARK_HIGH,NR_WMARK};structzone{/* ... */unsignedlongwatermark[NR_WMARK];// 该区域各种水线/* ... */};

最低水位以下的内存称为紧急保留内存,在内存严重不足的紧急情况下,给承诺“分给我们少量的紧急保留内存使用,我可以释放更多的内存”的进程使用。

Watermark水位控制内核选用了几个重要参数:

  • managed_pages: 伙伴分配器管理的物理页的数量
  • spanned_pages: 当前区域跨越的总页数,包括空洞
  • present_pages: 当前区域可用的所有物理页的数量,包括空洞

它们三者之间的关系:spanned_pages > present_pages > managed_pages

min_free_kbytes的计算:
min_free_kbytes代表的是系统保留空闲内存的最低限度。watermark[WMARK_MIN]的值是通过min_free_kbytes计算出来的。

5. 分区的伙伴分配器核心函数

入口函数:__alloc_pages_nodemask

参数说明:

  • gfp_mask: 分配标志(掩码)
  • order: 阶数
  • zonelist: 首选内存节点的备用区域列表
  • nodemask: 允许从哪些节点分配。如果是NULL,表示允许从所有节点分配。

5.1 快速路径分配页框

函数get_page_from_freelist用于尝试从备用区域列表的区域中分配页框。

它会遍历zonelist,对于每个zone,检查是否满足水位要求(zone_watermark_ok)。如果满足,则尝试从该zone分配。

5.2 慢速路径调用和遇到内存紧缺时的分析

如果在快速路径中分配失败,则会进入慢速路径(__alloc_pages_slowpath)。
慢速路径包含了更复杂的逻辑,例如:

  • 唤醒页回收线程(kswapd)。
  • 忽略水位限制进行分配(如果是紧急分配)。
  • 直接内存回收(Direct Reclaim)。
  • 调用 OOM Killer(如果配置允许)。
  • 重试分配等。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 9:19:14

【项目中的经验总结】

知识点一:多电源域下 Dummy Gate 的连接问题 1. 背景说明 在 MOS 管版图中,dummy gate 常用于满足工艺对栅极密度、对称性和边缘效应的要求。 Dummy gate 虽不参与功能,但仍具有栅氧层及栅-源 / 栅-漏寄生电容,不能视为“完全无效…

作者头像 李华
网站建设 2026/4/25 19:11:27

线性规划:库存切割问题

原文:towardsdatascience.com/linear-programming-the-stock-cutting-problem-dc6ba3bf3de1 本文深入探讨了线性规划如何解决一个称为“库存切割”的具体问题。在深入探讨本系列中的线性规划细节之前,我想提供一个具体的例子。本文将使用未在本文中定义的…

作者头像 李华
网站建设 2026/5/1 4:59:53

国抽对接规则

1、国抽可以同步下来 待填报之前的样品信息(包括正在接样状态)。 2、国抽可以同步下来 待填报且已维护基础表的项目信息(基础表维护按照报送分类B及细类维护,或特殊样品的项目维护)。

作者头像 李华
网站建设 2026/4/23 15:04:21

[特殊字符]️_开发效率与运行性能的平衡艺术[20260107171443]

作为一名经历过无数项目开发的工程师,我深知开发效率与运行性能之间的平衡是多么重要。在快节奏的互联网行业,我们既需要快速交付功能,又需要保证系统性能。今天我要分享的是如何在开发效率和运行性能之间找到最佳平衡点的实战经验。 &#…

作者头像 李华
网站建设 2026/5/1 5:46:09

c++ 17的std::variant对标c#的哪个类型

C# 的 System.Object、dynamic 和 C# 7.0 引入的 System.ValueTuple 以及 System.OneOf 等都可以实现类似功能,但最接近 C std::variant 语义的是:1. 官方方案:System.Object 和模式匹配(最接近)基础用法csharp// 类似…

作者头像 李华
网站建设 2026/4/23 19:36:26

狂揽77k Star!我用3分钟,给本地服务安上了公网域名

我经常需要在外面访问家里的 NAS,或者给客户演示我电脑上一个还没上线的项目。每次都被内网穿透搞得头疼不已,不是要研究复杂的路由器设置,就是要忍受那些又慢又不稳定的免费服务。传统内网穿透,太折腾了想靠自己搞定内网穿透&…

作者头像 李华