1. 程式人生 > >儲存器管理——記憶體分配(分割槽,段,頁)

儲存器管理——記憶體分配(分割槽,段,頁)

儲存器管理

連續分割槽兩種方式對比

固定分割槽 可變分割槽
分割槽記憶體大小 固定 可變
記憶體利用率 提高
內碎片 存在 不存在
外碎片 不存在 存在
碎片解決方案 緊縮技術
併發程式個數 固定 可變
記憶體管理資料結構 記憶體分配表 分割槽連結串列
記憶體分配策略 最先/最佳匹配法 最先/最佳/最壞/下次匹配法
記憶體回收策略 分割槽狀態 佔用 => 空閒 更新分割槽連結串列
記憶體保護策略 限長暫存器 限長暫存器

內碎片:程序所佔用的分割槽內部未被利用的空間
外碎片:各程序之間難以被利用的空閒區間

不變分割槽兩種策略

單個輸入佇列的

最先匹配法 最佳匹配法
解釋 找第一個可以裝入該分割槽的 搜尋整個佇列,選擇能裝入的該分割槽的最大程序
優/缺點 小程序可能浪費大的空間 減少空間的浪費

可變分割槽四種策略

最先 最壞 最佳 下次
解釋 找第一個 找最大的 找大小最為接近,使得外碎片最小 從上次找的地方再找找不到迴圈到前面去
優點 速度很快,高地址較大分割槽易於保留 不留下小的空閒分割槽 速度快,分佈均勻
缺點 大分割槽沒有保留下來 外碎片浪費 大分割槽不易保留

理解重定位

實體地址:記憶體地址,絕對地址,實地址
邏輯地址:相對地址,虛地址
地址對映 (地址重定位) :邏輯地址 ->實體地址

靜態重定位 動態重定位
區別 載入記憶體的時候指令地址固定 執行的時候指令地址固定
移動 此段程式載入記憶體後不可以移動 此段程式載入記憶體後可以移動
需求 不需要暫存器 需要基址暫存器

段頁儲存對比

頁式儲存 段式儲存
資料結構 頁表 & 物理頁面表 段表
邏輯頁號 & 記憶體塊號(物理頁面號) 段號 & 段起始地址 & 段長& 保護位
優點 沒有外碎片,內碎片也很小 分為多個模組,實現每個模組分別編寫,編譯,保護,段單位共享
程式不必連續存放 程式不必連續存放
缺點 程式必須全部裝入記憶體 程式必須全部裝入記憶體
維護頁表也是一筆開銷 存在外碎片

1. 頁儲存理解

因為是動態重定位:所以給出的是邏輯地址 高位變成邏輯頁面號(陣列下標) 低位則為頁內偏移
理解為什麼可以轉換:
程式以動態重定位方式進行,假如給的是8位邏輯地址,假如記憶體被分為16位元組一個塊,一共16個頁
從 0000 | 0000 到 1111|1111
0000 | 0000 第零頁的開始
0000 | 0011 第零頁的0011偏移量
0000 | 1111 第零頁的最後一塊 下一個內容就要翻一頁了
0001 | 0000 第一頁開始 同理
0001 | 1111 需要翻頁了
0002 | 0000 就是第二頁
假如給出的邏輯地址 0001 | 1111 現在知道頁數了
那麼要找到物理塊號 我們還有兩個問題
1.他是誰的第一頁?
2.頁表放在哪裡?
但一個程序建立都給出了頁表,那麼當這個程序執行的時候,他會把他的頁表的起始地址放在基址暫存器中,所以 第二個問題就解決了,第一個問題當然也解決了,你需要訪問的是在佔用CPU的,這時候你暫存器裡存的頁表起始地址就是他的第一頁,最後一個問題?
他是表裡面的哪一個?因為這樣才能找到塊號
頁表起始地址+頁號(右偏移四位)或 頁表起始地址+頁面大小*頁號
式子就是他 ,找到相應塊號,然後轉換成實體地址 假如塊號就是3 然後畢竟是 0011|1111
這樣完成了邏輯地址到實體地址轉換

這樣的壞處
兩次訪問記憶體,CPU訪問記憶體相當慢
解決方案
於是有了TLB 存放最近一段時間最常用的頁表項, 邏輯頁面號與 物理頁面號直接對應

2. 段儲存的理解

段儲存給出邏輯地址的本身就二維地址
同樣知道 假如給的是0001 | 1111 第一維段號 第二維段內偏移 同樣知道第一段
兩個問題?
1.他是誰的第一段?
2.段表放在哪裡?
但一個程序建立都給出了段表,那麼當這個程序執行的時候,他會把他的段表的起始地址放在基址暫存器中 還有個問題
他是表裡面的哪一個?
段表起始地址+段號(右偏移四位)
找到段的起始地址 多出來的操作就是 偏移量與得到段長比 是否越界!
段起始地址+偏移地址 就是實體地址

是不是兩者很像 主要是因為邏輯地址含義不一樣而已
段還有一種 ,學過8086處理器的知道
是直接在CS ,DS,SS,ES給出段起始地址 的