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