一、思考:連續分配方式的缺點?
考慮支持多道程序的兩種連續分配方式:
- 固定分區分配:缺乏靈活性,會產生大量的內部碎片,內存的利用率很低。
- 動態分區分配:會產生很多外部碎片,雖然可以用“緊湊”技術來處理,但是“緊湊”的時間代價很高。
如果允許將一個進程分散地裝入到許多不相鄰的分區中,便可充分地利用內存,而無需再進行“緊湊”。基於這一思想,產生了“非連續分配方式”,或者稱爲“離散分配方式”。
連續分配:爲用戶進程分配的必須是一個連續的內存空間。
非連續分配:爲用戶進程分配的可以是一些分散的內存空間。
二、把“固定分區分配”改造爲“非連續分配版本”
假設進程A大小爲23MB,但是每個分區大小隻有10MB,如果進程只能佔用一個分區,那顯然放不下。
解決思路:如果允許進程佔用多個分區,那麼可以把進程拆分成10MB+10MB+3MB三個部分,再把這三個部分分別放到三個分區中(這些分區不要求連續)。但是,進程A的最後一個部分是3MB,放入分區後會產生7MB的內部碎片。
如果每個分區大小爲2MB,那麼進程A可以拆分成11*2MB+1MB共12個部分,只有最後一部分1MB佔不滿分區,會產生1MB的內部碎片。
顯然,如果把分區大小設置的更小一些,內部碎片會更小,內存利用率會更高。
基本分頁存儲管理的思想——把內存分爲一個個相等的小分區,再按照分區大小把進程拆分成一個個小部分
三、分頁存儲管理的基本概念
將內存空間分爲一個個大小相等的分區(比如:每個分區4KB),每個分區就是一個“頁框”,或稱“頁幀”、“內存塊”、“物理塊”。每個頁框有一個編號,即“頁框號”(或者“內存塊號”、“頁幀號”、“物理塊號”)頁框號從0開始。
將用戶進程的地址空間也分爲與頁框大小相等的一個個區域,稱爲“頁”或“頁面”。每個頁面也有一個編號,即“頁號”,頁號也是從0開始。
(注:進程的最後一個頁面可能沒有一個頁框那麼大。因此,頁框不能太大,否則可能產生過大的內部碎片)
操作系統以頁框爲單位爲各個進程分配內存空間。進程的每個頁面分別放入一個頁框中。也就是說,進程的頁面與內存的頁框有一一對應的關係。各個頁面不必連續存放,也不必按先後順序來,可以放到不相鄰的各個頁框中。
四、思考:如何實現地址的轉換?
將進程地址空間分頁之後,操作系統該如何實現邏輯地址到物理地址的轉換?
先回顧一下,進程在內存中連續存放時,操作系統是如何實現邏輯地址到物理地址的轉換的?(採取動態重定位的方法)
五、如果採用分頁技術,應該如何實現地址轉換?
CPU執行指令1,需要訪問邏輯地址爲80的內存單元,如何轉化爲物理地址?
邏輯地址爲80的內存單元:
應該在1號頁,該頁在內存中的起始位置爲450,邏輯地址爲80的內存單元相對於該頁的起始地址而言,“偏移量”應該是30。
所以,實際物理地址=450+30=480
- 要算出邏輯地址對應的頁號
- 要知道該頁號對應頁面在內存中的起始地址
- 要算出邏輯地址在頁面內的“偏移量”
- 物理地址=頁面始址+頁內偏移量
如何計算:
頁號=邏輯地址/頁面長度(取除法的整數部分)
頁內偏移量=邏輯地址%頁面長度(取除法的餘數部分)
頁面在內存中的起始位置:操作系統需要用某種數據結構記錄進程各個頁面的起始位置。
頁號=80/50=1
頁內偏移量=80%50=30
1號頁在內存中存放的起始位置450
注意:爲了方便計算頁號、頁內偏移量,頁面大小一般設爲2的整數冪
結論:如果每個頁面大小爲2^K B,用二進制數表示邏輯地址,則末尾K位即爲頁內偏移量,其餘部分就是頁號
因此,如果讓每個頁面的大小爲2的整數冪,計算機就可以很方便地得出一個邏輯地址對應的頁號和頁內偏移量。
六、邏輯地址結構
分頁存儲管理的邏輯地址結構如下所示:
地址結構包含兩個部分:前一部分爲頁號,後一部分爲頁內偏移量W。在上圖所示的例子中,地址長度爲32位,其中0-11位爲“頁內偏移量”,或稱“頁內地址”;12-31位爲“頁號”。
如果有K位表示“頁內偏移量”,則說明該系統中一個頁面的大小是2^K個內存單元
如果有M位表示“頁號”,則說明在該系統中,一個進程最多允許有2^M個頁面
分頁存儲管理中,如何實現地址轉換?
- 要算出邏輯地址對應的頁號
- 要知道該頁是對應頁面在內存中的起始地址
- 要算出邏輯地址在頁面內的“偏移量”
- 物理地址=頁面始址+頁內偏移量
注:如果題目中是用十進制數表示邏輯地址,則頁號=邏輯地址/頁面長度(取除法的整數部分)頁內偏移量=邏輯地址%頁面長度(取除法的餘數部分)
七、頁表
爲了能知道進程的每個頁面在內存中存放的位置,操作系統要爲每個進程建立一張頁表。
爲什麼每個頁表項的長度是相同的,頁號是“隱含”的?
Eg:假設某系統物理內存大小爲4GB,頁面大小爲4KB,則每個頁表項至少應該爲多少字節?
4GB=2^32B,
4KB=2^12B
因此4GB的內存總共會被分爲2^32 / 2^12= 220個內存塊**,因此內存塊號的範圍應該是0~220-1因此至少要20個二進制位才能表示這麼多的內存塊號,因此至少要3個字節纔夠(每個字節8個二進制位,3個字節共24個二進制位)
各頁表項會按順序連續地存放在內存中。如果該頁表在內存中存放的起始地址爲x,則M號頁對應的頁表項一定是存放在內存地址爲 X+3*M。因此,頁表中的“頁號”可以是“隱含”的。
只需要知道頁表存放的起始地址和頁表項長度**,即可找到各個頁號對應的頁表項存放的位置。在本例中,一個頁表項佔3B,如果進程由n個頁面,則該進程的頁表總共會佔3*n個字節。