可變分區記憶體管理是作業系統核心課程中的經典主題。本模擬旨在實作 最差適配演算法,讓學習者理解動態分區分配、回收與碎片整理的完整流程。最差適配策略每次尋找 最大的空閒分區 進行分配,理論上能保留較大的連續空間供大型作業使用,但也容易產生難以利用的微小碎片。
相較於靜態的「已分配區表」與「空閒區表」,空閒鏈結串列 更適合動態環境:
起始位址、大小、下一節點指標。struct FreeBlock {
size_t start_addr;
size_t size;
FreeBlock* next;
};
size >= request_size 且 size 最大 的節點。start_addr 遞增、size 遞減,返回原起始位址。回收時需依歸還區塊的起始位址,插入空閒鏈結串列並檢查前後相鄰區塊:
prev.start + prev.size == curr.start) → 合併至前一節點。curr.start + curr.size == next.start) → 合併至下一節點。將所有已分配區塊向低位址緊湊移動,更新進程的基址暫存器,最後將所有空閒區合併為一個大塊。此操作需暫停所有進程,屬高成本操作,通常在分配失敗時才觸發。
class MemoryManager {
FreeBlock* free_list_head;
vector allocated_list; // 記錄已分配區塊:PID, start, size
public:
bool allocate(int pid, size_t size, size_t& out_addr);
bool deallocate(int pid);
void compact(); // 碎片整理
void print_status() const; // 列印當前分區圖
};
| 步驟 | 操作 | 預期結果 |
|---|---|---|
| 1 | 初始化 640KB 記憶體 | 單一空閒區 [0, 640K] |
| 2 | 分配 P1: 100K | 取最大空閒區 → P1得 [0,100K],剩餘 [100K,540K] |
| 3 | 分配 P2: 200K | 取剩餘最大 → P2得 [100K,200K],剩餘 [300K,340K] |
| 4 | 回收 P1 | 空閒區合併 → [0,100K] + [300K,340K](不相鄰,兩塊) |
| 5 | 分配 P3: 300K | 最差適配選 [300K,340K] → P3得 [300K,300K],剩 [600K,40K] |
| 6 | 碎片整理 | P2移至 [0,200K],P3移至 [200K,300K],空閒合併為 [500K,140K] |
完整原始碼與詳細註解可參考百度文庫資源:
最差適配記憶體分配模擬實作
透過空閒鏈結串列實作最差適配演算法,能深入體會動態記憶體管理的精髓。建議學習者在掌握基本流程後,嘗試加入「最佳適配」、「首次適配」等策略進行比較分析,並嘗試模擬多執行緒併發分配場景,進一步理解鎖機制與效能權衡。