內存管理學習筆記 :
操作系統---內存管理(上) 概念 覆蓋交換技術 連續分配管理方式
操作系統---內存管理(下) 分段存儲 段頁式存儲 虛擬內存 請求分頁管理方式
大綱
什么是內存
內存是用於存放數據的硬件
程序執行前需要先放到內存中才能被cpu處理
存儲單元
如果計算機"按字節編址", 每個存儲單元大小為8 bit
如果計算機"按字編址", 每個存儲單元大小為16 bit
邏輯地址和物理地址
指令的編指一般采用邏輯地址, 即相對地址
物理地址 = 起始地址 + 邏輯地址 (理解)
編譯, 鏈接, 裝入
編譯 : 由編譯程序將用戶源代碼編譯成若干個目標模塊
鏈接 : 由連接程序將編譯后形成的一組目標模塊以及所需函數連接在一起, 形成一個完整的裝入模塊
鏈接的三種方式 :
- 靜態鏈接-----裝入模塊不再拆開
- 裝入時動態鏈接-----將各目標模塊裝入內存時, 邊裝入邊鏈接的連接方式
- 運行時動態鏈接-----在程序執行中需要該目標模塊時才對它進行鏈接
裝入 : 由裝入程序將裝入模塊裝入內存運行
裝入的三種方式:
- 絕對裝入
- 靜態重定位
- 動態重定位
絕對裝入 : 在編譯時, 如果知道程序將放到內存的哪個位置, 編譯程序將產生絕對地址的目標代碼, 裝入程序按照裝入模塊中的地址, 將程序和數據裝入內存 ------靈活性低, 只適合單道程序環境
靜態重定位 : 又稱為可重定位裝入. 編譯, 鏈接后的裝入模塊地址都是從0開始的, 指令中使用的地址和數據存放的地址都是相對於起始地址而言的邏輯地址. 可以根據內存的當前狀況將裝入模塊裝入到內存的適當位置. 裝入時對地址進行"重定位", 邏輯地址變換為物理地址(地址變換是在裝入時一次完成的).
動態重定位 : 裝入程序把裝入模塊裝入內存后不會立即把邏輯地址轉換為物理地址, 而是把地址轉換推遲到程序真正要執行時才進行. 因此裝入內存后所有的地址依然是邏輯地址. 這種方式需要一個重定位寄存器(存放裝入模塊的起始位置)的支持
內存管理的概念
進程應該放在內存的哪里?
操作系統如何記錄哪些內存區域已經被分配了, 哪些還空閑?
當進程運行結束之后, 如何將進程占用的內存空間釋放?
-
操作系統負責內存空間的分配與回收
-
操作系統需要提供某種技術從邏輯上對內存空間進行擴充
-
操作系統需要實現地址轉換功能, 負責程序的邏輯地址和物理地址的轉換
-
操作系統需要提供內存保護功能, 保證各進程在各自存儲空間內運行, 互不干擾
實現內存保護的兩種方法:- 在CPU設置一對上, 下限寄存器, 存放進程的上, 下限地址. 進程的指令要訪問某個地址時, CPU檢查是否越界
- 采用重定位寄存器(又叫基地址寄存器) 和界地址寄存器(又叫限長寄存器) 進行越界檢查. 重定位寄存器中存放的是進程的起始物理地址, 界地址寄存器中存放的是進程的最大邏輯地址.
內存空間的擴充
覆蓋與交換
覆蓋, 交換, 虛擬存儲技術常用於實現內存空間的擴充
覆蓋技術
覆蓋技術的思想 : 將程序分為多個段, 常用的段常駐內存, 不常用的段在需要的時候調入內存
內存中分為一個"固定區" 和若干個"覆蓋區", 常用的段放在固定區, 不常用的段放在覆蓋區
缺點 : 必須由程序員聲明覆蓋結構, 對用戶不透明, 增加了用戶的編程負擔, 覆蓋技術只用於早期的操作系統中.
交換技術
交換技術的思想 : 內存空間緊張時, 系統將內存中某些進程暫時換出外存, 把外存中某些已具備運行條件的進程換入內存(即進程在內存與磁盤間動態調度)
內存空間的分配和回收
連續分配管理方式
單一連續分配
在單一連續分配的方式中, 內存被分為系統區和用戶區, 系統區用於存放操作系統的相關數據, 用戶區用於存放用戶進程的相關數據, 內存中只能有一道用戶程序, 用戶程序獨占整個用戶區空間.
-
優點 : 實現簡單, 無外部碎片; 可以采用覆蓋技術擴充內存; 不一定需要采取內存保護
-
缺點 : 只能用於單用戶, 單任務的操作系統中; 有內部碎片; 存儲器利用率極低
內部碎片 : 分配給某進程的內存區域有一部分沒有用上, 即存在" 內部碎片 ".
外部碎片 : 內存中的某些空閑分區由於太小而難以利用
固定分區分配
在產生了支持多道程序的系統后, 為了能在內存中裝入多道程序而互相之間不產生干擾, 將整個用戶區划分為若干個固定大小的分區(分區大小可以相等也可以不相等), 在每個分區中只能裝入一道作業, 形成了最早的可運行多道程序的內存管理方式.
操作系統建立一個數據結構----分區說明表, 來實現各個分區的分配和回收, 每個表對應一個分區, 通常按分區大小排列. 每個表項包括對應分區的大小, 起始地址, 狀態
-
優點 : 實現簡單, 無外部碎片;
-
缺點 : 有內部碎片; 存儲器利用率不高;
動態分區分配
動態分區分配又稱為可變分區分配, 這種分配方式不會預先划分內存分區. 而是在進程裝入內存時根據進程大小動態地建立分區, 並使得分區的大小正好適合進程的需要.
幾個問題 :
- 系統用什么數據結構記錄內存的使用情況?
- 當多個空閑分區都滿足需求應該選擇哪個分區進行分配?
- 如何進行分區的分配和回收操作?
常用的數據結構 :
空閑分區表, 空閑分區鏈
動態分配不會產生內部碎片, 而會產生外部碎片, 外部碎片可以通過" 緊湊"的方式解決(把基地址遷移)
四種動態分配的算法
- 首次適應算法
每次都從低地址開始查找, 找到第一個能滿足大小的空閑分區
實現 : 把空閑分區按地址遞增的次序排列.
每次分配內存時順序地查找空閑分區鏈, 找到大小能滿足要求的第一個空閑分區.
- 最佳適應算法
優先使用小的空閑分區
實現 : 空閑分區按容量遞增次序鏈接.
每次分配內存時順序查找空閑分區鏈, 找到大小能滿足要求的第一個空閑分區
缺點 : 每次都選擇最小的分區進行分配, 會留下越來越多的容量很小難以利用的內存塊, 即產生很多的外部碎片
- 最壞適應算法
優先使用大的空閑分區
實現 : 空閑分區按容量遞減次序鏈接
缺點 : 每次都選用最大的分區進行分配, 當較大的連續空閑區被小號之后, 如果有大進程到來則沒有內存分區可以利用
- 鄰近適應算法
在首次適應算法的基礎上, 每次都從上次查找結束的位置開始查找空閑分區鏈(表), 找到大小能滿足的第一個空閑分區
缺點 : 鄰近適應算法導致無論低地址還是高地址的空閑分區都有相同的概率被使用, 也就導致了高地址部分的大分區更可能被使用划分為小分區, 最后導致沒有大分區可用
綜合來看, 首次適應算法的性能最好
算法開銷大 : 最佳適應法, 最壞適應法 ( 需要經常排序)
算法開銷小 : 首次適應算法, 鄰近適應算法
ref : https://www.bilibili.com/video/BV1YE411D7nH?p=36
王道考研視頻的學習筆記, 順便重新用ppt畫了一下圖, 主要是學習一下ppt作圖..