文章目錄
- 前言
- 摘要
- 一、從內存分配失敗説起
- 二、內存分區管理核心原理
- 2.1 連續分配 vs 非連續分配
- 2.2 內部碎片 vs 外部碎片
- 三、固定分區分配
- 3.1 固定分區原理
- 四、動態分區分配
- 4.1 動態分區原理
- 4.2 動態分區分配算法
- 4.3 詳細分配示例
- 五、緊湊與夥伴系統
- 5.1 緊湊技術
- 5.2 夥伴系統
- 六、內存分區管理總結
- 6.1 核心要點
- 6.2 考研408重點
前言
內存分區管理是操作系統內存管理的基礎。為什麼固定分區會產生內部碎片?動態分區為什麼會有外部碎片?首次適應、最佳適應、最壞適應有什麼區別?夥伴系統如何減少碎片? 理解連續分配策略、分區分配算法、碎片問題、緊湊技術,才能掌握內存管理的基礎原理。
摘要
從"內存碎片導致分配失敗"故障出發,剖析內存分區管理的核心原理。通過固定分區的內部碎片分析、動態分區的分配算法對比、外部碎片的緊湊解決、夥伴系統的折中策略,揭秘連續內存分配的完整機制。配合詳細計算推導,給出碎片率、分配效率的透徹理解。
一、從內存分配失敗説起
週三上午,哈吉米啓動程序失敗:
場景1:空閒內存夠但無法分配
系統狀態:
物理內存:8GB
已分配:6GB
空閒:2GB
啓動程序:
需要內存:1.5GB
結果:
分配失敗!
查看內存:
空閒塊1:500MB
空閒塊2:600MB
空閒塊3:400MB
空閒塊4:500MB
總空閒:2GB > 1.5GB ✓
但沒有連續的1.5GB塊 ❌
哈吉米:“總空閒內存夠,為什麼分配不了?”
南北綠豆:“這是外部碎片——空閒內存分散,無法滿足大塊分配。”
場景2:固定分區的浪費
固定分區方案:
分區1:1GB(分配給進程A,實際用500MB)
分區2:1GB(分配給進程B,實際用800MB)
分區3:1GB(分配給進程C,實際用900MB)
分區4:1GB(空閒)
浪費空間:
分區1浪費:500MB
分區2浪費:200MB
分區3浪費:100MB
總浪費:800MB
哈吉米:“分配了1GB但只用了一部分,浪費了。”
阿西噶阿西:“這是內部碎片——分配的塊內有未使用空間。”
二、內存分區管理核心原理
2.1 連續分配 vs 非連續分配
南北綠豆:“內存分配分為連續和非連續兩大類。”
|
分配方式
|
説明
|
優點
|
缺點
|
|
連續分配 |
進程佔用連續內存
|
簡單、訪問快
|
碎片、不靈活
|
|
非連續分配 |
進程可佔用分散內存
|
無外部碎片、靈活
|
複雜、需要頁表
|
連續分配方式:
- 固定分區
- 動態分區
- 夥伴系統
非連續分配方式:
- 分頁(已講)
- 分段
- 段頁式
2.2 內部碎片 vs 外部碎片
碎片類型對比:
|
類型
|
定義
|
產生原因
|
解決方法
|
|
內部碎片 |
分配塊內的未使用空間
|
分配單位大於需求
|
減小分配單位
|
|
外部碎片 |
分配塊之間的未使用空間
|
分配釋放導致分散
|
緊湊、非連續分配
|
圖示:
內部碎片:
|------ 分配的1GB ------|
|已使用500MB|內部碎片500MB|
外部碎片:
|進程A|外部碎片|進程B|外部碎片|進程C|
↑ ↑
100MB 200MB
分散,無法合併使用
生活化比喻:
停車場場景:
內部碎片:
車位(分配單位):5米
汽車(實際需求):4米
浪費:1米(內部碎片)
外部碎片:
|車1|空1米|車2|空0.5米|車3|
↑ ↑
分散的空位,停不進新車(外部碎片)
哈吉米:“內部碎片在塊內,外部碎片在塊間。”
三、固定分區分配
3.1 固定分區原理
原理:將內存劃分為若干固定大小的分區。
分區方案:
方案1:分區大小相等
|1MB|1MB|1MB|1MB|1MB|1MB|1MB|1MB|
優點:簡單
缺點:大進程裝不下,小進程浪費大
方案2:分區大小不等
|512K|512K|1MB|1MB|2MB|2MB|4MB|
優點:靈活
缺點:仍有內部碎片
分配數據結構:
分區表:
| 分區號 | 起始地址 | 大小 | 狀態 | 進程號 |
|--------|---------|------|------|--------|
| 1 | 0x0000 | 512K | 空閒 | - |
| 2 | 0x0800 | 512K | 已分配| P1 |
| 3 | 0x1000 | 1MB | 空閒 | - |
| 4 | 0x2000 | 2MB | 已分配| P2 |
分配流程圖:
graph TB
Start[進程請求內存] --> Size[檢查所需大小]
Size --> Search[查找分區表]
Search --> Find{找到合適空閒分區?}
Find -->|是| Check{分區大小≥需求?}
Check -->|是| Alloc[分配分區]
Alloc --> Update[更新分區表]
Update --> Success[分配成功]
Check -->|否| Find
Find -->|否| Fail[分配失敗]
Success --> Frag[產生內部碎片]
內部碎片計算:
例子:
進程需求:700KB
分配分區:1MB
內部碎片 = 1024KB - 700KB = 324KB
碎片率 = 324 / 1024 = 31.6%
南北綠豆:“固定分區簡單但浪費大,現代系統很少用。”
四、動態分區分配
4.1 動態分區原理
原理:根據進程需求動態劃分內存,分區大小可變。
分配示例:
初始狀態:
|--------- 8GB空閒 ---------|
分配進程P1(1GB):
|-- P1(1GB) --|-- 7GB空閒 --|
分配進程P2(2GB):
|P1(1GB)|-- P2(2GB) --|5GB空閒|
分配進程P3(1.5GB):
|P1|P2|-- P3(1.5GB) --|3.5GB空閒|
釋放P2:
|P1|-- 2GB空閒 --|P3|3.5GB空閒|
↑ 外部碎片產生
空閒分區鏈表:
空閒分區表:
| 起始地址 | 大小 | 下一個 |
|---------|------|--------|
| 0x1000 | 2GB | → |
| 0x5000 | 3.5GB| NULL |
4.2 動態分區分配算法
首次適應(First Fit):
原理:
從頭開始查找,分配第一個足夠大的空閒塊
例子:
空閒塊:[10MB, 5MB, 20MB, 15MB]
需求:12MB
掃描:
10MB < 12MB ❌
5MB < 12MB ❌
20MB ≥ 12MB ✓ 分配這個
結果:
分配20MB中的12MB
剩餘8MB加入空閒鏈表
最佳適應(Best Fit):
原理:
查找最接近需求的空閒塊(浪費最小)
例子:
空閒塊:[10MB, 5MB, 20MB, 15MB]
需求:12MB
掃描所有:
10MB:差2MB ❌
5MB:差7MB ❌
20MB:差8MB
15MB:差3MB ← 最接近 ✓
結果:
分配15MB中的12MB
剩餘3MB(小碎片)
最壞適應(Worst Fit):
原理:
分配最大的空閒塊(剩餘塊儘量大)
例子:
空閒塊:[10MB, 5MB, 20MB, 15MB]
需求:12MB
找最大:
20MB ← 最大 ✓
結果:
分配20MB中的12MB
剩餘8MB(較大,可再利用)
三種算法對比:
|
算法
|
策略
|
優點
|
缺點
|
適用
|
|
首次適應 |
第一個夠用的
|
快速
|
前端碎片多
|
通用⭐
|
|
最佳適應 |
最接近的
|
浪費小
|
產生小碎片,慢
|
內存緊張時
|
|
最壞適應 |
最大的
|
剩餘塊大
|
大塊很快用完
|
很少用
|
算法對比示意圖:
首次適應FF
最佳適應BF
最壞適應WF
空閒塊1:10MB
空閒塊2:5MB
空閒塊3:20MB選中
空閒塊1:10MB
空閒塊2:5MB
空閒塊3:20MB
空閒塊4:15MB選中
空閒塊1:10MB
空閒塊2:5MB
空閒塊3:20MB選中
空閒塊4:15MB
哈吉米:“首次適應最快,最佳適應最省,最壞適應用得少。”
4.3 詳細分配示例
問題:
初始空閒塊:[20KB, 10KB, 30KB, 15KB]
請求序列:
1. 分配12KB
2. 分配10KB
3. 釋放12KB
4. 分配15KB
分別用首次適應、最佳適應、最壞適應,畫出每步狀態
首次適應:
|
操作
|
空閒塊狀態
|
説明
|
|
初始
|
[20, 10, 30, 15]
|
-
|
|
分配12KB
|
[8, 10, 30, 15]
|
從20KB分配(首個夠用)
|
|
分配10KB
|
[8, 0, 30, 15]
|
從10KB分配(剛好)
|
|
釋放12KB
|
[8, 0, 30, 15, 12]
|
12KB加入尾部
|
|
分配15KB
|
[8, 0, 15, 15, 12]
|
從30KB分配
|
最佳適應:
|
操作
|
空閒塊狀態
|
説明
|
|
初始
|
[20, 10, 30, 15]
|
-
|
|
分配12KB
|
[20, 10, 30, 3]
|
從15KB分配(最接近)
|
|
分配10KB
|
[20, 0, 30, 3]
|
從10KB分配(剛好)
|
|
釋放12KB
|
[20, 0, 30, 3, 12]
|
12KB加入尾部
|
|
分配15KB
|
[5, 0, 30, 3, 12]
|
從20KB分配(最接近)
|
最壞適應:
|
操作
|
空閒塊狀態
|
説明
|
|
初始
|
[20, 10, 30, 15]
|
-
|
|
分配12KB
|
[20, 10, 18, 15]
|
從30KB分配(最大)
|
|
分配10KB
|
[10, 10, 18, 15]
|
從20KB分配(最大)
|
|
釋放12KB
|
[10, 10, 18, 15, 12]
|
12KB加入尾部
|
|
分配15KB
|
[10, 10, 3, 15, 12]
|
從18KB分配(最大)
|
阿西噶阿西:“不同算法導致碎片分佈不同。”
五、緊湊與夥伴系統
5.1 緊湊技術
原理:移動進程,合併空閒碎片。
緊湊過程:
緊湊前:
|P1|碎片1|P2|碎片2|P3|碎片3|
|2MB|1MB|3MB|2MB|1MB|3MB|
緊湊後:
|P1|P2|P3|------ 空閒6MB ------|
|2MB|3MB|1MB|
緊湊時序圖:
操作系統 進程P1 進程P2 進程P3 暫停所有進程 保持位置不動 移動到P1後面 更新頁表/地址 移動到P2後面 更新頁表/地址 合併尾部空閒區 恢復所有進程 操作系統 進程P1 進程P2 進程P3
緊湊開銷:
|
開銷
|
説明
|
|
時間 |
移動數據需要時間(GB級數據秒級)
|
|
暫停進程 |
緊湊期間進程暫停
|
|
更新地址 |
需要更新所有地址指針
|
緊湊時機:
1. 空閒碎片過多時
2. 無法分配大塊時
3. 系統空閒時
南北綠豆:“緊湊解決外部碎片,但開銷大。”
5.2 夥伴系統
原理:折中方案,塊大小為2的冪,易於分裂與合併。
夥伴系統規則:
塊大小:
1KB, 2KB, 4KB, 8KB, 16KB, ..., 512KB, 1MB
分配規則:
1. 向上取整到2的冪
2. 從對應大小鏈表取塊
3. 如果沒有,從更大塊分裂
釋放規則:
1. 釋放塊加入鏈表
2. 檢查夥伴是否空閒
3. 如果夥伴空閒,合併成大塊
夥伴計算:
夥伴判斷:
兩個塊大小相同
地址相鄰
起始地址滿足:addr % (2 × size) == 0
例子:
塊A:起始0x0000,大小64KB
塊B:起始0x10000,大小64KB
檢查:
大小相同 ✓
相鄰 ✓
0x0000 % 128KB = 0 ✓
→ A和B是夥伴
夥伴系統示例:
初始:1MB空閒
請求70KB:
向上取整:128KB
分裂過程:
1MB → 512KB + 512KB(分裂)
512KB → 256KB + 256KB(分裂)
256KB → 128KB + 128KB(分裂)
分配:128KB
結果:
已分配:128KB(給進程)
空閒:128KB, 256KB, 512KB
夥伴系統結構圖:
分配與釋放過程:
|
操作
|
過程
|
結果
|
|
分配70KB |
向上→128KB,從256KB分裂
|
分配128KB,剩餘128KB
|
|
分配35KB |
向上→64KB,從128KB分裂
|
分配64KB,剩餘64KB
|
|
釋放70KB |
釋放128KB,與夥伴合併
|
合併為256KB
|
夥伴系統優缺點:
優點:
✓ 分配快(鏈表查找)
✓ 易於合併(夥伴檢查)
✓ 碎片較少
缺點:
✗ 有內部碎片(向上取整)
✗ 某些大小浪費大(如65KB→128KB)
哈吉米:“夥伴系統是固定和動態的折中。”
六、內存分區管理總結
6.1 核心要點
南北綠豆總結:
- 連續分配:進程佔用連續內存,簡單但有碎片
- 固定分區:塊大小固定,有內部碎片
- 動態分區:塊大小可變,有外部碎片
- 分配算法:首次適應(快)、最佳適應(省)、最壞適應(少用)
- 緊湊:移動進程合併碎片,開銷大
- 夥伴系統:折中方案,塊大小為2的冪
6.2 考研408重點
阿西噶阿西:
必考題型:
✓ 內部碎片vs外部碎片
✓ 首次適應、最佳適應、最壞適應模擬
✓ 碎片率計算
✓ 夥伴系統分配過程
✓ 緊湊前後內存佈局
必記公式:
✓ 內部碎片 = 分配大小 - 實際需求
✓ 碎片率 = 碎片大小 / 分配大小
✓ 夥伴系統:向上取整到2的冪
必記要點:
✓ 內部碎片:分配塊內浪費
✓ 外部碎片:分配塊間分散
✓ 首次適應:快速,前端碎片多
✓ 最佳適應:省空間,產生小碎片
✓ 最壞適應:剩餘塊大,很少用
✓ 緊湊:移動進程,合併碎片
✓ 夥伴系統:塊大小為2^n
計算技巧:
✓ 畫表格模擬分配過程
✓ 標註每個空閒塊的大小
✓ 首次適應:從頭掃描
✓ 最佳適應:掃描全部,選最小夠用
✓ 最壞適應:掃描全部,選最大
✓ 夥伴系統:向上取整到2^n
典型考題:
題:空閒塊[20KB, 10KB, 30KB],請求序列12KB, 10KB, 15KB,
用首次適應,畫出每步狀態
答:
初始:[20, 10, 30]
分配12KB:[8, 10, 30](從20KB分配)
分配10KB:[8, 0, 30](從10KB分配)
分配15KB:[8, 0, 15](從30KB分配)
哈吉米:“掌握了內存分區管理,408內存管理基礎就完全理解了。”
參考資料:
- 《操作系統概念》(第9版)- Abraham Silberschatz
- 《現代操作系統》(第4版)- Andrew S. Tanenbaum
- 《計算機操作系統》(第4版)- 湯小丹
- 408統考大綱 - 操作系統部分