1. 为什么我们需要页面分配算法
现代操作系统管理内存的核心机制之一就是分页(Paging)。想象一下,你正在玩一个大型拼图游戏,整个拼图被分割成许多相同大小的小块。操作系统管理内存的方式与此类似——它将物理内存划分为固定大小的"页框"(Page Frame),同时将进程的地址空间划分为相同大小的"页"(Page)。当进程需要内存时,操作系统负责将这些"页"分配到可用的"页框"中。
页面分配算法要解决的核心问题是:当有多个空闲页框可用时,应该选择哪一个来满足当前的内存分配请求?这个看似简单的选择背后,隐藏着对系统性能的深远影响。一个好的页面分配算法能够:
- 减少内存碎片(既包括内部碎片也包括外部碎片)
- 提高缓存命中率
- 均衡内存使用
- 为后续的内存分配预留空间
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 常见页面分配算法详解
2.1 首次适应算法(First-Fit)
首次适应算法是最直观的分配策略。它维护一个空闲页框列表,当收到分配请求时,从列表头部开始扫描,选择第一个足够大的空闲块进行分配。
c复制struct page *first_fit_alloc(size_t size) {
struct page *current = free_list_head;
while (current != NULL) {
if (current->size >= size) {
// 找到合适块,进行分割或全部分配
return split_or_allocate(current, size);
}
current = current->next;
}
return NULL; // 没有找到合适块
}
优点:
- 实现简单,分配速度快
- 倾向于保留大块空闲内存
缺点:
- 容易在低地址区域产生碎片
- 分配不均匀,可能导致后续大块请求无法满足
2.2 最佳适应算法(Best-Fit)
最佳适应算法试图找到能满足请求的最小空闲块。这需要遍历整个空闲列表,找到大小最接近请求的空闲块。
c复制struct page *best_fit_alloc(size_t size) {
struct page *best = NULL;
struct page *current = free_list_head;
while (current != NULL) {
if (current->size >= size) {
if (best == NULL || current->size < best->size) {
best = current;
}
}
current
