作業系統-記憶體管理
阿新 • • 發佈:2020-07-27
記憶體管理的目標:
- 實現記憶體的分配和回收
- 合理的分配記憶體空間,提高記憶體利用率,提高記憶體訪問速度
## 儲存器的層次結構
速度由快到慢,容量由小到大,價格由高到低
**暫存器->L1快取記憶體 -> L2快取記憶體 -> 主儲存器 -> 本地二級儲存 -> 遠端二級儲存(web/ftp)**
特點:每個層級的儲存器都儲存來自下一級儲存器的資訊
分類:
- 其中位於CPU內部的是:暫存器->L1快取記憶體 -> L2快取記憶體
- 其中統稱為記憶體的是:暫存器->L1快取記憶體 -> L2快取記憶體 -> 主儲存器
- 其中統稱為外存/輔助儲存的是:本地二級儲存 -> 遠端二級儲存(web/ftp)
## 區域性性原理
定義:在一段時間內,程式的執行僅限於某個部分,相應的,它所訪問的儲存空間也侷限於某個區域
**分類**
- 時間區域性性
- 程式的執行僅限於某個部分(某幾條指令)
- 某指令一旦被執行,不久之後該指令將再次被執行
- 空間區域性性
- 程式所訪問的記憶體僅限於某個部分,
- 若某個單元的記憶體被訪問,則附近的單元將很快被訪問
## 程式的連結
### 靜態連結
含義: 程式被編譯後會變成一個一個的獨立模組(比如用到的各種庫),在執行前,需要使用連結程式將目標模組連結成一個完整的裝入模組
特點:執行速度相對快,但佔用記憶體更多
**連結程式的具體任務**
- 連結程式的任務
- 對邏輯地址進行修改
- 連結程式的任務2
- 變換外部呼叫符號
- 外部認為程式依然是整體的,所以使用的是Call,但是現在程式被分成不同模組,所以連結程式需要將外部的call變換為JSR(跳轉至子程式)
### 動態連結
含義:可將目標模組的連結推遲到這這寫模組中的函式被呼叫時才進行;
特點:執行速度相對慢,但是可以節省記憶體
## 程式的裝入
連線程式完成連線後得到一個裝入模組,裝入程式負責將這個裝入模組裝入到記憶體中
#### 絕對裝入方式
編譯時產生**實體地址**的目的碼
#### 重定位裝入方式
- 可重定位裝入方式(靜態重定位) ,編譯時地址是邏輯地址, **裝入時通過重定位轉換為實體地址**
- 動態執行時裝入(動態重定位),程式**執行時**通過重定位轉為實體地址
實際地址 = 邏輯地址 + 物理其實地址
## 連續分配儲存管理方式
### 單一連續分配
任何時刻主儲存器最多隻有一個作業
### 固定分割槽分配
- 將記憶體分為固定大小的若干個分割槽,每個分割槽可以且僅可以裝入一個作業
- 根據系統不同,分割槽大小可以是相等也可以是相等的
- 每個分割槽有上限暫存器和下限暫存器,統稱為界限暫存器,用於保護記憶體
- 維護一個`固定分割槽說明表`用於記錄分割槽的使用情況
![image-20200726210422462](https://gitee.com/yangyuanhuyyh/MDimage/raw/master/uPic/image-20200726210422462.png)
### 動態分割槽分配
- 分割槽大小**不是預先固定的**,而是按照作業的實際需求來劃分的
- 分割槽的**個數也不是預先固定**的,而是由能裝入的作業數決定的
- 維護一個`空閒分割槽表`,用於記錄當前可用的分割槽資訊
![image-20200726211224753](https://gitee.com/yangyuanhuyyh/MDimage/raw/master/uPic/image-20200726211224753.png)
- 與空閒分割槽表功能相同的還有另一種叫做`空閒分割槽鏈`
- 本質是一個雙向連結串列,每個節點包含一個指向前一個和一個指向後一個分割槽的指標,以及一個儲存可用分割槽起始地址和長度的資料域;
![image-20200726212123929](https://gitee.com/yangyuanhuyyh/MDimage/raw/master/uPic/image-20200726212123929.png)
### 動態分割槽分配演算法
#### 首次適應演算法
- 空閒分割槽鏈以地址遞增的順序連結,從鏈首開始查詢直至找到第一個滿足條件的分割槽
- 從該分割槽中劃出一塊記憶體給程序,剩下的分割槽資訊仍然留在空閒鏈中
- 該方式的不足
- 外部碎片,分配後剩下的一點點留在分割槽鏈中,由於空間較小,無法被有效利用
- 內部碎片已經分配個某個程序的空間,但程序不需要那麼多,空閒了一部分
#### 迴圈首次適應演算法
- 唯一與首次適應演算法不同的就是,維護了一個分割槽指標,每次分配完成,該指標往後移動一個位置;
- 該方式可使得空閒區分佈較均勻,但是依然會產生碎片
#### 最佳適應發
- 每次分配前需將分割槽鏈節點按照空閒空間大小從小到大排序
- 遍歷分割槽鏈,查詢第一個滿足條件的分割槽分配給程序,
- 該方式可使得每次分配都能儘可能找到與程序需求最接近的分割槽,減少碎片產生,提高利用率
### 動態分割槽分配流程
設使用最佳適應演算法,流程已經介紹不在囉嗦
1. 對分割槽鏈按照大小升序排序
2. 遍歷分割槽鏈在找到可用分割槽後,從分割槽中劃出區域給程序
3. 更新分割槽鏈資訊
例:設找到的分割槽起始位置為S,長度為L, 程序需要的大小為N
- 分配完成後,新的起始位置為:S + N, 長度為L - N
- 重新對分割槽鏈按空間大小升序排序
### 動態分割槽回收流程
1. 釋放一塊連續的記憶體區域
2. 如果被釋放的區域與其他空閒區域前後相鄰則將前後相鄰的分割槽合併,無論在前在後
3. 如果沒有相鄰的,則建立新節點儲存分割槽資訊
4. 修改分割槽鏈資訊
例:
- 設釋放的區域起始地址為A,長度為L
- 判斷否相鄰:設已有空閒分割槽起始位置為X,長度為Y
- 若 X+Y == A ,則表示前面有相鄰, 則合併後空閒分割槽起始地址為X,長度為Y + L
- 若 A+L == X,則表示後面有相鄰,則合併後空閒分割槽起始地址為A,長度