文章目錄
4.1 存儲器的層次結構
ROM:只讀
RAM:可讀可寫
◼ 主存儲器與寄存器
主存儲器:可執行存儲器
寄存器:訪問速度最快。
◼ 高速緩存和磁盤緩存
高速緩存:訪問速度快於主存儲器
磁盤緩存:利用主存中的存儲空間。
4.2 程序的裝入和鏈接 (數據進入內存)
在多道程序環境下,要使程序運行,必須爲之先建立進程
創建進程的第一件事是將程序和數據裝入內存。
4.2.0 將用戶源程序變爲可在內存中執行的程序的步驟:
- 編譯:由編譯程序將用戶源代碼編譯成若干個目標模塊
- 鏈接:由鏈接程序將編譯後形成的一組目標模塊,以及它們所需要的庫函數鏈接在一起,形成一個完整的裝入模塊
- 裝入:由裝入程序將裝入模塊裝入內存
4.2.1 程序的裝入
將一個裝入模塊裝入內存時,有三種方式:
- 絕對裝入方式
- 可重定位裝入方式
- 動態運行時裝入方式
1. 絕對裝入方式:(直接告訴你具體位置)
在編譯時,如果知道程序駐留在內存的什麼位置,那麼編譯程序將產生絕對地址的目標代碼。
裝入模塊裝入內存後,程序中的邏輯地址與實際內存地址完全相同,不須對程序和數據的地址進行修改。
程序中所使用的絕對地址,可在編譯或彙編時給出,也可由程序員賦予。通常在程序中採用符號地址,然後在編譯或彙編時,再將這些符號地址轉換爲絕對地址。
機器語言無變量概念,一切數據通過地址訪問。
2. 可重定位裝入方式:(裝入數據時會修改命令的地址,使之合理)
絕對裝入方式只能將目標模塊裝入到內存中事先指定 的位置。在多道程序環境下,編譯程序不能預知所編譯的 目標模塊應放在內存何處,因此絕對裝入方式只適用於單 道程序環境下。
在多道程序環境下,目標模塊的起始地址通常從0開始, 程序中的其他地址都是相對於起始地址計算的。因此應採 用可重定位裝入方式,根據內存的當前情況,將裝入模塊 裝入到內存的適當位置。
注意:在採用可重定位裝入方式將裝入模塊裝入內存後,會使裝入模塊中的所有邏輯地址與實際裝入內存的物理地址不同。
3. 動態運行時裝入方式:
可重定位裝入方式,可將裝入模塊裝入到內存中任何允許的位置,故可用於多道程序環境;但並不允許程序運行時在內存中移動位置。
實際上,在運行過程中程序在內存中的位置可能經常要改變。動態運行時的裝入程序,在把裝入模塊裝入內存後,並不立即把裝入模塊中的相對地址轉換爲絕對地址,而是把這種地址轉換推遲到程序
真正要執行時才進行。
因此,裝入內存後的所有地址都仍是相對地址。
爲使地址轉換不影響指令的執行速度,應設置一個重定位寄存器。
4.2.2 程序的鏈接
程序經過編譯後得到一組目標模塊,再利用鏈接程序將目標模塊鏈接,形成裝入模塊。
根據鏈接時間的不同,把鏈接分成三種:
-
靜態鏈接:
在程序運行前,將目標模塊及所需的庫函數鏈接成一個完整的裝配模塊,以後不再拆開。 -
裝入時動態鏈接:
指將用戶源程序編譯後所得的一組目標模塊, 在裝入內存時,採用邊裝入邊鏈接的鏈接方式。 -
運行時動態鏈接:
指對某些目標模塊的鏈接,是在程序執行中需要該目標模塊時,纔對它進行鏈接。
1. 靜態鏈接方式:事先進行鏈接,以後不再拆開
2. 裝入時動態鏈接
用戶源程序經編譯後所得的目標模塊,是在裝入內存時,
邊裝入邊鏈接的,即在裝入一個目標模塊時,若發生一個外
部模塊調用事件,將引起裝入程序去找出相應的外部目標模
塊,並將它裝入內存,還要修改目標模塊中的相對地址。
優點:
- 便於修改和更新
- 便於實現對目標模塊的共享
3. 運行時動態鏈接
在許多情況下,應用程序要運行的模塊可能不同,事 先不知道要運行哪些模塊,只能全部裝入,裝入時全部鏈 接在一起,效率低。
運行時動態鏈接是將對某些模塊的鏈接推遲到執行時 才執行,即在執行過程中,當發現一個被調用模塊尚未裝 入內存時,立即由OS去找到該模塊並將之裝入內存,把 它鏈接到調用者模塊上。凡執行過程中未被用到的目標模 塊,不會調入內存和鏈接,這樣不僅加快程序的裝入過程, 而且節省大量的內存空間。
4.3 連續分配存儲器管理方式(整塊全部裝入,不拆開)
連續分配方式,是指爲一個用戶程序分配一個連續的內存空間。
內存利用率低,並且不能擴充,後續引入離散方式。
4.3.1 單一連續分配(就一整塊,不分開)
最簡單的一種存儲管理方式,但只能用於單用戶、單任務的操作系統中。
採用這種存儲管理方式時,可把內存分爲系統區和用戶區兩部分,
系統區僅提供給OS使用,通常放在內存低址部分,
用戶區是指除系統區以外的全部內存空間,提供給用戶使用。
4.3.2 固定分區分配(提前劃分固定大小)
-
原理 將內存用戶空間劃分爲若干個固定大小的區域,在每個分區 中只裝入一道作業,這樣把用戶空間劃分爲幾個分區,便允許有 幾道作業併發執行。當有一空閒分區時,便可以再從外存的後備 作業隊列中,選擇一個適當大小的作業裝入該分區,當該作業結 束時,可再從後備作業隊列中找出另一作業調入該分區。
-
劃分分區的方法 可用兩種方法將內存的用戶空間劃分爲若干個固定大小的分區:
(1) 分區大小相等:缺乏靈活性,用於一臺計算機控制多個相同對 象的場合
(2) 分區大小不等:把內存區劃分成含有多個較小的分區、適量的 中等分區及少量的大分區,可根據程序的大小爲之分配適當 的分區。
-
實現
爲便於內存分配,通常將分區按大小進行排隊,併爲之建立一張分區使用表,其中各表項包括每個分區的起始地址、大小及狀態(是否已分配)。當有一用戶程序要裝入時,由內存分配程序檢索該表,從中找出一個能滿足要求的、尚未分配的分區,將之分配給該程序,然後將該表項中的狀態置爲“已分配”;若未找到大小足夠的分區,則拒絕爲該用戶程序分配內存。
4.3.3 動態分區分配
1. 原理:
動態分區分配是根據進程的實際需要,動態地爲之分配內存空間。
作業裝入內存時,把可用內存分出一個連續區域給作業,且分區的大小正好適合作業大小的需要。分區的大小和個數依裝入作業的需要而定。
2. 實現:
在實現過程中涉及如下問題:
-
分區分配中的數據結構
(1)空閒分區表示- 空閒分區表:記錄每個空閒分區的情況。每個空閒分區佔一個表目。
表目中包括:分區序號、分區始址、分區的大小等。 - 空閒分區鏈:在每個分區的起始部分,設置一些用於控制分區分配的信息,以及用於鏈接各分區所用的前向指針;在分區尾部則設置一後向指針,在分區末尾重複設置狀態位和分區大小表目。(雙向鏈表)
(2)已佔分區說明表
結構:作業號;起始地址;大小
- 空閒分區表:記錄每個空閒分區的情況。每個空閒分區佔一個表目。
-
分區分配算法
爲把一個新作業裝入內存,需按照一定的分配算法,從
空閒分區表或空閒分區鏈中選出一分區分配給該作業。
常用的分配算法:-
(1) 首次適應算法FF
FF算法要求空閒分區表以 地址遞增 的次序排列。在分配內存時,從表首開始順序查找,直至找到一個大小能滿足要求的空閒分區爲止;然後按照作業的大小,從該分區中劃出一塊內存空間分配給請求者,餘下的空閒分區仍留在空閒分區表中。若從頭到尾不存在滿足要求的分區,則分配失敗。優點:優先利用內存低址部分的內存空間
缺點:低址部分不斷劃分,產生小碎片(內存碎塊、內存碎片、零 頭);每次查找從低址部分開始,增加了查找的開銷 -
(2) 循環首次適應算法
在分配內存空間時,從上次找到的空閒分區的下一個空閒分區開始查找,直到找到一個能滿足要求的空閒分區,從中劃出一塊與請求大小相等的內存空間分配給作業。爲實現算法,需要:
1.設置一起始查尋指針
2.採用循環查找方式優點:使內存空閒分區分佈均勻,減少查找的開銷
缺點:缺乏大的空閒分區 -
(3) 最佳適應算法
所謂“最佳”是指每次爲作業分配內存時,總是把能
滿足要求、又是最小的空閒分區分配給作業,避免“大材
小用”。要求將所有的空閒分區按其容量以從小到大的順序形 成一空閒分區鏈。
缺點:產生許多難以利用的小空閒區
-
-
分區分配及回收操作
利用某種分配算法,從空閒分區鏈(表)中找到所需大小的 分區。設請求的分區大小爲u.size,表中每個空閒分區的大小表 示爲m.size,若m.size - u.size <=size(規定的不再切割的分區大 小),將整個分區分配給請求者,否則從分區中按請求的大小劃 出一塊內存空間分配出去,餘下部分留在空閒鏈中,將分配區首址返回給調用者。
回收內存
當進程運行完畢釋放內存時,系統根據回收區首址,在空閒分區鏈(表)中找到相應插入點,此時可能有四種情況:- 回收區與插入點的前一個分區F1鄰接:將回收區與F1合併,修改F1的表項的分區大小
- 回收區與插入點的後一個分區F2鄰接:將回收區與F2合併,修改F2的表項的首址、分區大小
- 回收區與插入點的前後兩個分區F1、F2鄰接:將三個分區合併,使用F1的表項和F1的首址,取消F2的表項,大小爲三者之和
- 回收區既不與F1鄰接,又不與F2鄰接:爲回收區單獨建立新表項,填寫回收區的首址與大小,根據其首址插到空閒鏈中的適當位置
4.3.4 可重定位分區分配
-
動態重定位的引入
在連續分配方式中,必須把系統或用戶程序裝入一連續的內存空間。如果在統統中只有若干個小分區,即使它們的容量總和大於要裝入的程序,但由於這些分區不相鄰,所以無法將程序裝入內存。
解決方法:將內存中的所有作業進行移動,使它們全部鄰接,這樣可把原來分散的小分區拼接成大分區,這種方法稱爲“拼接”或“緊湊”。
缺點:用戶程序在內存中的地址發生變化,必須重定位。
-
動態重定位的實現
在動態運行時裝入的方式時,將相對地址轉換爲物理地址的工作在程序指令真正要執行時才進行。地址轉換需要重定位寄存器 (額外的) 的支持。程序執行時訪問的內存地址是相對地址與重定位寄存器中的地址相加而成。地址變換過程是在程序執行過程期間,隨着對每條指令的訪問自動進行的,稱爲動態重定位。
4.4 對換(Swapping)
4.4.1 引入
多道程序環境下存在的問題:
- 阻塞進程佔據大量內存空間
- 許多作業在外存而不能進入內存運行
對換:把內存中暫時不能運行的進程或者暫時不用的程序和數據, 調到外存上,以便騰出足夠的內存空間,再把已具備運行條件的 進程和進程所需要的程序和數據,調入內存。
對換的分類:
- ➢ 整體對換(或進程對換):以整個進程爲單位
- ➢ 頁面對換或分段對換:以頁或段爲單位
實現進程對換,系統必須具備的功能:
- ➢ 對換空間的管理 (關鍵)
- ➢ 進程的換出
- ➢ 進程的換入
4.4.2 對換空間的管理 (關鍵)
一般從磁盤上劃出一塊空間作爲對換區使
在系統中設置相應的數據結構以記錄外存的使用情況
對換空間的分配與回收,與動態分區方式時的內存分配與回收雷同(幾乎完全一樣)。
4.4.3 進程的換出與換入
◼ 進程的換出
換出過程:系統首先選擇處於阻塞狀態且優先級最低的進程作爲換出進程,然後啓動盤塊,將該進程的程序和數據傳送到磁盤的對換區上。
(一般pcb很小,而且pcb有表示狀態作用,需要留着去排隊或證明身份)
◼ 進程的換入
換入過程:系統應定時查看所有進程的狀態,從中找出“就緒”狀態但已換出的進程,將換出進程最久的進程作爲換入進程,將之換入,直至已無可換入的進程或無可換出的進程爲止。
4.5 分頁存儲管理方式
連續分配方式會形成“碎片”,雖然可以通過“緊湊”解決,但開銷大。如果允許將一個進程直接分散地裝入許多不相鄰的分區中,則無需“緊湊”,由此產生離散分配方式。
分類:
- 分頁存儲管理方式:離散分配的基本單位是頁
- 分段存儲管理方式:離散分配的基本單位是段
基本的分頁存儲管理方式(或純分頁存儲管理方式):
不具備頁面對換功能,不具有支持實現虛擬存儲器的功能,要求把每個作業全部裝入內存後方能運行。
4.5.1 頁面與頁表
# 1. 頁面
-
➢ 分頁式存儲管理的原理
分頁存儲管理是將一個進程的邏輯地址空間 (作業地址空間) 分成若干個大小 相等的片稱爲頁面或頁,併爲各頁加以編號,從0開始。同時把 內存空間分成與頁面相同大小的若干個存儲塊,稱爲塊或頁框。 在爲進程分配內存時,以塊爲單位將進程的若干個頁分別裝入 到多個可以不相鄰的物理塊中。
進程的最後一頁經常裝不滿而形成“頁內碎片”。
存在頁內碎片,但是沒有問題,不影響,最後會一起回收 -
➢基本分頁式存儲管理(簡單頁式存儲管理)的原理
系統若能滿足一個作業所要求的全部塊數,此作業才能被 裝入內存,否則不爲它分配任何內存。
-
➢ 請求分頁式存儲管理的原理
運行一個作業時,並不要求把該作業的全部程序和數據都 裝入內存,可以只把目前要執行的幾頁調入內存的空閒塊中, 其餘的仍保存在外存中,以後根據作業運行的需要再調入內存。
-
➢ 頁面大小的選擇
一臺機器就一種大小
◼ 由機器的地址結構所決定的,即由硬件所決定。
◼ 某一種機器只能採用一種大小的頁面。
◼ 通常是:幾KB到幾十KB。
➢ 小:內碎片小,內存利用率高,但頁面數目多,使頁表過長,佔大量內存,管理開銷大;
➢ 大:頁表短,管理開銷小,內碎片大,內存利用率低
4.5.1 頁面與頁表
- ➢ 頁面大小
頁面大小應選的適中,應是2的冪,通常是512B~8KB。
可以不連續,
邏輯地址到物理地址的轉換,
每個作業一張頁表,空閒塊表整個系統一張
# 2. 地址結構
邏輯地址到物理地址的轉換:
地址長度32位:
0~11位爲位移量(頁內地址),即每頁的大小爲4KB
12~31位爲頁號,地址空間最多允許有1M頁
數值的表示:
二進制,十進制,八進制,十六進制,分別在其後加上B,D,Q,H. 如: 十進制的1,用二進制表示爲1B,八進制爲1Q,十六進制爲1H.
# 3. 基本分頁式存儲管理(簡單頁式存儲管理)的實現
在分頁系統中,允許進程的每一頁離散地存儲在內存的任一存儲塊中,爲方便查找,系統爲每一進程建立一張頁面映像表,簡稱頁表。頁表實現了從頁號到物理塊號的地址映射。
在頁表表項中常設置一存取控制字段,對存儲塊內容加以保護。
4.5.2 地址變換機構
地址變換機構實現從邏輯地址到物理地址的轉換,其任務是藉助於頁表,將邏輯地址中的頁號轉換爲內存中的物理塊號。
1. 基本的地址變換機構
頁表的功能可以由一組專門的寄存器來實現,一個頁表項用一個寄存器。但寄存器成本高,系統頁表可能很大,所以頁表大多常駐內存。
在系統中只設置一個頁表寄存器PTR,在其中存放頁表在內
存中的始址和頁表的長度。(當前CPU作業的頁表地址與長度)
2. 具有快表的地址變換機構
CPU在每存取一個數據時,需要兩次訪問內存:
第一次:訪問頁表,找到指定頁的物理塊號,將塊號與頁內偏移量拼接形成物理地址。
第二次:從第一次所得地址中獲得所需數據,或向此地址中寫入數據。
存儲器利用率提高,處理器處理速度降低。
解決方法:在地址變換機構中,增設一個具有並行查尋能力的特殊高速緩衝寄存器,稱爲“聯想存儲器”或“快表”。(頁表放快表裏面)
4.5.3 兩級和多級頁表
現代計算機系統都支持非常大的邏輯地址空間(2的32~2的64),
頁表就非常大,需佔用較大的地址空間。
例如:一個具有32位邏輯地址空間的分頁系統,規定頁面大小 爲4KB即212B,則每個進程頁表的頁表項可達1M個,若每個頁表 項佔用一個字節,則每個進程的頁表就要佔據1MB的內存空間,而且要求連續存放。
解決方法:
➢ 採用離散方式
➢ 只將當前所需頁表項調入內存
- 兩級頁表
將頁表分頁,並離散地將各個頁面分別存放在不同的物理 塊中,同時爲離散分配的頁表在建立一張頁表,稱爲外層頁表, 其每個頁表項記錄了頁表頁面的物理塊號。
例如: 32位邏輯地址空間,頁面大小爲4KB(即12位),若採用 一級頁表機構,應有20位頁號,即頁表項應有1M個;在採用 兩級頁表機構時,再對頁表進行分頁,使每頁包含210(即1024) 個頁表項,最多允許有210個頁表分頁。即
訪問三次內存:
- 兩級頁表
上述方法用離散分配空間解決了大頁表無需大片存 儲空間的問題,但並未減少頁表所佔的內存空間。
解決方法是把當前需要的一批頁表項調入內存,以 後再根據需要陸續調入。
- 多級頁表
兩級頁表對32位機器適用,64位呢?
頁面大小爲4KB即212B,還剩52位,按物理塊大小212 位來劃分頁表,則剩餘40位用於外層頁號,此時外層頁 表可能有1024G個頁表項,要佔用4096GB的連續存儲空 間
解決方法:採用多級頁表,將外層頁表再進行分頁。
4.6 分段存儲管理方式
按照功能來分,不再是強硬分的。
4.6.1 分段存儲管理方式的引入
- ◼ 便於編程:
用戶常把自己的作業按邏輯關係劃分成若干個段,每段都有自己的名,且都從零開始編址,這樣,用戶程序在執行中可用段 名和段內地址進行訪問。 例如:LOAD 1,[A] | 。 - ◼ 分段共享:
在實現程序和數據的共享時,常常以信息的邏輯單位爲基礎, 而分頁系統中的每一頁只是存放信息的物理單位,其本身沒有完整 的意義,因而不便於實現信息的共享,而段卻是信息的邏輯單位, 有利於信息的共享。 - ◼ 分段保護:
信息保護是對相對完整意義的邏輯單位(段)進行保護。 - ◼ 動態鏈接:
當運行過程中又需要調用某段時,再將該段(目標程序) 調入內存並鏈接起來。所以,動態鏈接是以段爲基礎的。 - ◼ 動態增長:
在實際系統中,有些數據段會不斷地增長,而事先卻無法知道 數據段會增長到多大,分段存儲管理方式能較好地解決這個問題。
4.6.2 分段系統的基本原理
# 1. 分段
在分段存儲管理方式中,作業地址空間被劃分爲若干個段,每個段定義了一組邏輯信息,都有自己的名字。通常用段號代替段名,每段從0開始編址,並採用一段連續地址空間。
段長由邏輯信息組的長度決定。整個作業的地址空間分成多個 段,邏輯地址由段號(段名)和段內地址所組成。
該地址結構允許一個作業最長有64K個段,每段的最大長度
三原理
-
◼ 分段式存儲管理的原理
作業分爲若干個段。每段分配一個連續的內存區,由於各段的長度不等,這些區域也就大小不一。作業各段間不要求連續。 -
◼ 基本分段式存儲管理的原理
在段式存儲管理原理的基礎上,要求將整個作業的全部段裝入內存。 -
◼ 請求分段式存儲管理的原理
在段式存儲管理原理的基礎上,不要求將整個作業的全部段裝入內存。只裝入作業的幾段即可運行,其餘段可根據運行的需要再裝入內存。
#2. 基本分段式存儲管理的實現
- 1)段表
在分段式存儲管理系統中,系統爲每個分段分配一個連續的分區,而進程中的各個段可以離散地移入內存中不同的分區中。
爲使程序正常運行,須在系統中爲每個進程建立一張段映射表,簡稱“段表”。每個段在表中佔有一個表項。
段表結構:段號;段在內存中的起始地址(基址);段長。
段表可以存放在寄存器中,但更多的是存放在內存中。
段表用於實現從邏輯段到物理內存區的映射
- 2)地址變換機構
在系統中設置段表寄存器,用於存放段表始址和段表長度,以實現從進程的邏輯地址到物理地址的變換。
當段表存放在內存中時,每訪問一個數據,都需訪問兩次內存,降低了計算機的速率。
解決方法:設置聯想寄存器,用於保存最近常用的段表項。
作業表,段表,空閒分區表。
- 3)分頁和分段的主要區別
相似點:
採用離散分配方式,通過地址映射機構實現地址變換
不同點:
◼ 頁是信息的物理單位,分頁是爲了滿足系統的需要;
段是信息的邏輯單位,含有一組意義相對完整的信息,分段是爲了滿足用戶
的需要。
◼ 頁的大小固定且由系統確定,由系統把邏輯地址分爲頁號和頁內
地址,由機器硬件實現;段的長度不固定,取決於用戶程序,編
譯程序對源程序編譯時根據信息的性質劃分。
◼ 分頁的作業地址空間是一維的;分段的作業地址空間是二維的。
4.6.3 信息共享
分段系統的一個突出優點是易於實現段的共享和保護,允許若干個進程共享一個或多個分段,且對段的保護十分簡單易行。
分頁系統中雖然也能實現程序和數據的共享,但遠不如分段系統方便。
在分段系統中,實現共享十分容易,只需在每個 進程的段表中爲共享程序設置一個段表項。
可重入代碼又稱爲純代碼,是一種允許多個進程同時訪問 的代碼,可重入代碼不允許任何進程對它進行修改。
◼ 可重入代碼(Reentrant Code):
又稱爲“純代碼”(Pure Code),在實現段共享時,需要用到可重入代碼(Reentrant Code) 。它是一種允許多個進程同時訪問的代碼,是一種不允許任何進程對其進行修改的代碼。
在每個進程中,配以局部數據區,將在執行中可能改變的部分,拷貝到該數據區,這樣,程序在執行時,只對該數據區(屬於該進程私有)中的內容進行修改,而不去改變共享的代碼,這時的 可共享代碼即成爲可重入代碼。
4.6.4 段頁式存儲管理方式
分段和分頁存儲管理方式各有優缺點。 把兩者結合成一種新的存儲管理方式——段頁式存儲管理方式, 具有兩者的長處。 1. 基本原理 先將用戶程序分成若干段,再把每個段分成若干頁,併爲 每個段賦予一個段名。 基本段頁式存儲管理:把作業的所有段裝入內存方可運行。 請求段頁式存儲管理:沒必要把整個作業裝入內存,可把作業 的幾段或幾頁裝入內存即可運行。 在段頁式系統中,地址結構:段號;段內頁號;頁內地址。
- 實現
在段頁式系統中,爲了實現地址變換,增加一個
段表寄存器,用來存放段表始址和段長。
在段頁式系統中,爲了獲得一條指令或數據,需訪問三次內存:
第一次:訪問內存中的段表,取得頁表始址
第二次:訪問內存中的頁表,取得該頁所在的物理塊號,將塊號
與頁內地址形成物理地址
第三次:訪問第二次所得的地址,取出指令或數據
缺點:訪存次數增加兩倍
解決方法:增設高速緩衝寄存器