OS-儲存器管理
第四章儲存器管理
儲存器管理最主要的物件是記憶體的管理
儲存器的層次結構
由於幾乎每條指令都涉及儲存器的訪問,所以對速度有很高要求
對儲存器的三個要求
- 儲存器的訪問速度要快,能與處理機速度匹配
- 儲存器容量要大
- 儲存器價格要便宜
但這三個條件目前無法同時滿足,於是現代計算機系統無一例外地採用了多層結構的儲存器系統
多層結構的儲存器系統
儲存層次至少三級,從高到低為:CPU暫存器,主存,輔存
細分可以如下六層,層次越高,訪問速度越快,價格越高,容量越小
可執行儲存器
兩者又被稱為可執行儲存器,程序可以使用一條load或store指令對可執行儲存器進行訪問,但對輔存的訪問則需要通過I/O裝置實現
主儲存器
- 簡稱記憶體或主存,用於儲存程序執行時的程式和資料
- 主儲存器訪問速度遠低於CPU執行指令的速度
暫存器
- 主要用於存放處理機執行時的資料,以加速儲存器的訪問速度
- 具有和處理機相同的速度,訪問速度最快,但價格高昂
快取
快取記憶體
- 主要用於備份主存中較常用的資料,以減少處理機對主儲存器的訪問次數(區域性性原理)
- 作用是緩和記憶體和處理機之間的矛盾,大幅度提高程式執行速度
磁碟快取
- 主要用於暫時存放頻繁使用的一部分磁碟資料和資訊,以減少訪問磁碟的次數
- 本身並非是實際存在的儲存器,而是利用主存中部分儲存空間暫時存放從磁碟讀取的資訊,主存也可以看作輔存的快取記憶體
程式的裝入和連結
程式要在系統中執行,需經過
- 編譯:編譯程式對源程式進行編譯,形成若干目標模組
- 連結:連結程式將目標模組以及所需的庫函式連結在一起,形成完整的裝入模組
- 裝入:裝入程式將裝入模組裝入記憶體
裝入方式
絕對裝入方式
-
裝入前就修改成實體地址
-
裝入前完全知道程式將駐留在記憶體什麼位置,裝入後程序的邏輯地址(相對地址)與實際地址(實體地址)完全相同。
-
只適用於單道程式環境
可重定位裝入方式
- 裝入時修改地址
- 裝入時,裝入程式會把裝入模組裝入到記憶體合適的位置,即重定位地址,每個程式起始地址本來為0
- 指令的邏輯地址+裝入記憶體位置的起始地址=正確的實體地址
- 地址變換通常在程序裝入時一次完成,故又稱為靜態重定位
動態執行時的裝入方式
- 用到指令時修改地址(CPU支援,效率高)
- 裝入程式在把裝入模組裝入記憶體後,不立即把裝入模組中的邏輯地址轉換為實體地址,而是推遲到程式執行時才進行
- 在具有對換功能的系統中,一個程序可能多次換出換入,每次換入後的位置不同,則應採用該方式
連結方式
靜態連結方式
- 在程式執行之前,先將各目標模組及它們所需的庫函式連結成一個完整的裝配模組,以後不再拆開的方式
- 將多個目標模組裝配成一個裝入模組需解決
- 對相對地址進行修改
- 變換外部呼叫符號,即將新的相對地址替換原來的起始地址
裝入時動態連結方式
- 裝入一個目標模組時,若發生外部模組呼叫事件,將引起裝入程式去找出相應的外部目標模組,並將它裝入記憶體,同時還有修改目標模組的相對地址
- 優點:
- 便於修改和更新
- 便於實現對目標模組的共享
執行時動態連結方式
- 將某些模組的連結推遲到程式執行時才進行
- 即凡在執行過程中未被用到的目標模組,都不會被調入記憶體和被連結到裝入模組上
- 加快了程式的裝入過程,節省了大量記憶體空間
連續分配儲存管理方式
單一連續分配
在單道程式環境下,記憶體分為系統區和使用者區。使用者區僅裝有一個使用者程式,即整個記憶體都被該程式獨佔。
固定分割槽分配
為了能在記憶體中裝入多道程式,且使程式之間不會相互干擾,則將整個使用者空間劃分為若干個固定大小的區域,每個分割槽中只裝入一道作業
分割槽大小固定,導致程式太小時造成記憶體浪費,太大時又裝入失敗
動態分割槽分配
又稱可變分割槽分配,根據程序實際需要,動態地為之分配記憶體空間
資料結構
常用如下資料結構描述空閒分割槽和已分配分割槽情況
動態分割槽分配演算法
-
基於順序搜尋的動態分割槽分配演算法
-
首次適應
-
空閒分割槽鏈的地址為增序,在分配地址時從鏈首開始查詢,找到第一個大小可滿足的空閒分割槽為止
-
再按作業大小從該分區分出一塊記憶體,其餘部分仍作為空閒區留在空閒鏈中;整條鏈內都無法找到滿足的分割槽即分配失敗。
-
顯然該演算法傾向於優先利用低位地址的空閒分割槽,保留了高位地址的大空閒區,為大作業預留了空間,但同時也會造成低址部分留下大量記憶體碎片
-
-
迴圈首次適應
- 為了避免低址存在大量的記憶體碎片而改進的演算法
- 使用額外的起始查詢指標保留上一次找到的空閒分割槽的下一分割槽的地址,下次查詢時從此地址開始查詢,並且採用迴圈查詢方式。
-
最佳適應:找最接近的 (效率最低)(Best Fit,BF)
- 總是把能滿足要求的、最小的空閒分割槽分配給作業
- 後果:每次分配後剩餘的部分也是最小的,即產生許多難以利用的記憶體碎片
-
最壞適應:找最大的(Worst Fit,WF)
- 與最佳適應相反,每次都選取最大的空閒分割槽
- 要使效率最高,使最大的放前面
-
-
基於索引搜尋的動態分割槽分配演算法
- 快速適應(Quick Fit,QF)
- 又稱分類搜尋法,把具有相同容量的所有空閒分割槽單獨設定一個空閒分割槽連結串列,再設立一張管理索引表管理所有分割槽表
- 在進行分配時,先根據程序長度從索引表找到能容納它的最小空閒區大小對應的連結串列,然後直接取出其中的第一塊即可
- 此做法並不分割分割槽。優點即不產生碎片,查詢效率高
- 缺點是為了有效合併分割槽,演算法複雜,系統開銷大
- 夥伴系統
- 規定分割槽大小必須為2的冪
- 當需要為程序分配長度n的儲存空間時,先找到i,使得
2^(i-1)<n<=2^i
,然後就在空間分割槽大小為2^i的空閒分割槽連結串列中查詢- 若找到,則分配給該程序
- 若找不到,則往更大一級空閒分割槽連結串列中查詢,如2^(i+1)
- 若存在
2^(i+1)
空閒分割槽,則將其分為相等的兩個分割槽(進行k次切割),稱為一對夥伴,一個用於分配,一個加入小一級的2^i
空閒分割槽連結串列中 - 若不存在,繼續往更大一級空閒分割槽連結串列中查詢,直到大於可利用空間容量則結束
- 若存在
- 回收時也可能需要多次合併,若存在與待回收分割槽相同大小的分割槽則合併這兩個分割槽,並把合併分割槽歸入下一級分割槽鏈,若下一級分割槽同樣存在該情況,則依次合併
- 優於QF演算法,但比順序搜尋演算法差
- 雜湊演算法
- 以空閒分割槽大小為關鍵字構建雜湊表,從而在分割槽分配時快速得出分割槽連結串列表頭指標。
- 快速適應(Quick Fit,QF)
分割槽分配和回收操作
-
分配記憶體
設請求分割槽大小為u.size,每個空閒分割槽大小為m.size,size為規定的不再切割的剩餘分割槽大小界限
-
回收記憶體
可能出現的情況
- 回收區與插入點的前一個空閒分割槽F1相鄰接,則二者合併,修改前一分割槽F1大小
- 回收區與插入點的後一個空閒分割槽F2相鄰接,則二者合併,F1分割槽首址改為回收區首址,修改前一分割槽F1大小
- 回收區與插入點的前後兩分割槽F1,F2鄰接,則三者合併,用F1的表項和首址,取消F2的表項,大小為三者之和
- 回收區不與誰相鄰接,為其單獨建立一個新表項,填寫其首址和大小,並將首址插入空閒鏈適當位置
動態可重定位分割槽分配
緊湊演算法
之前提到分割槽分配剩下來不能被利用的小分割槽稱為碎片,而緊湊演算法就是把記憶體中所有作業移動,使其相鄰接,從而把分數的多個空閒小分割槽拼接成大分割槽
緊湊雖然提高了記憶體利用率,但緊湊後的使用者程式在記憶體中位置發生了變化,若不對程式和資料地址進行變換,程式將無法執行
每緊湊一次就變換一次,麻煩且影響效率,從而引入動態重定位
動態重定位
之前介紹的動態執行時裝入,就是把作業相對地址(邏輯地址)轉換為絕對(物理)地址的工作推遲到程式真正執行時進行,而這個操作需要硬體地址變換機構支援,即是在系統增設重定位暫存器。
地址變換過程是在程式執行期間,隨著每條指令或資料的訪問自動進行的,故稱為動態重定位
重定位暫存器的存在使得緊湊操作僅需修改暫存器儲存的程式起始地址即可
動態重定位分割槽分配演算法
在動態分割槽分配演算法基礎上增加了緊湊功能
對換
又稱為交換技術
指把記憶體中暫時不能執行的緊湊或者暫時不用的程式和資料換出到外存上,以騰出足夠記憶體空間,把已具備執行條件的程序或程序所需的資料和程式換入記憶體
有利於提高記憶體利用率,提高處理機利用率和系統吞吐量
對換型別
- 整體對換
- 用於多道程式系統中,作為處理機中級排程
- 頁面/分段對換
- 對換以程序的一個頁面或分段為單位
- 目的是支援虛擬儲存系統
為了實現程序對換,系統需實現三方面功能:對對換空間的管理,程序的換出,程序的換入
對換空間的管理
對換空間管理的主要目標
在具有對換功能的OS中,通常把磁碟空間分為檔案區和對換區
- 對檔案區的管理的主要目標
- 檔案長時間駐留在外存,訪問頻率低
- 提高檔案儲存空間利用率,然後才是提高檔案訪問速度
- 採取離散分配方式
- 對對換空間的管理的主要目標
- 程序駐留時間短,對換頻率高
- 提高程序換出換入速度,然後才是提高檔案儲存空間利用率
- 採取連續分配方式
對換區空閒盤塊管理中的資料結構,分配和回收
與動態分割槽分配方式類似,同樣使用空閒分割槽表或空閒分割槽鏈,分配回收也是類似
程序的換出與換入
程序換出
- 選擇被換出
- 檢查所有駐留在記憶體中的程序
- 若有處於阻塞狀態或睡眠狀態的程序,優先選擇
- 最後選擇優先順序最低的程序
- 程序換出
- 只能換出非共享的程式和資料段,而共享部分只要有程序還需要就不能換出
- 先申請對換空間
- 申請成功則啟動磁碟,將該程序資料和程式傳送到磁碟的對換區上
- 若傳送過程正常,則可回收該程序所佔用的記憶體空間,並對該程序的相關資料結構進行修改
程序換入
- 檢視PCB集合中所有程序狀態
- 找出就緒狀態但已換出的程序
- 選擇已換出時間最久的程序,為它申請記憶體
- 申請成功則直接將其從外存調入
- 申請失敗則先將記憶體中某些程序換出,直到記憶體空間足夠再調入
- 反覆以上步驟,直到記憶體無就緒且換出狀態的程序為止;或者已經無足夠記憶體換入為止
分頁儲存管理方式
基本思想
連續分配方式會形成很多碎片,雖然可通過緊湊演算法拼湊成可用的大空間,但開銷大,若允許一個程序直接分散地裝入許多不相鄰接的分割槽中,便可充分利用記憶體空間,且無須緊湊。
由此產生了離散分配方式。
分頁儲存管理方式思想
將使用者程式的地址空間分為若干個固定大小的區域,稱為頁,相應地也將記憶體空間分為若干物理塊,頁和塊大小相同,這樣可將使用者程式的任一頁放入任一物理塊中,實現離散分配
分頁儲存管理的基本方法
頁面和物理塊
-
頁面
-
分頁儲存管理將程序邏輯地址空間分成若干頁,併為之編號;也將記憶體實體地址空間分成若干塊,為之編號。
-
在分配記憶體時,以塊為單位,把程序中若干頁分別裝入不相鄰接的物理塊中
用不完一塊,也要佔用一塊的空間
由於最後一頁經常裝不滿一塊,形成頁內碎片
-
-
頁面大小
- 頁面過小則減少記憶體碎片,有利於提高記憶體利用率,但導致頁表過長,佔用記憶體多
- 頁面過大則頁內碎片增大
- 頁面大小應是2的冪
地址結構
地址結構=頁號+位(偏)移量(頁內地址)
若給定一個邏輯地址空間中地址為A,頁面大小L,則頁號P和頁內地址d可按下式求,INT是整除函式,MOD是取餘函式
例:其系統頁面大小L=1KB=1024B,A=2170B,
則2170/1024=2,餘122,P=2,d=122
頁表
為了能在記憶體中找到每個頁面對應的物理塊,系統為每個程序建立了一張頁面映像表,簡稱頁表
頁表的表項會設定存取控制欄位,用於規定為讀/寫,只讀,只執行等存取方式
例題:假設每一塊大小為1000(十進位制),那麼邏輯地址499,4399對應的實體地址是?
解:499/1000=0,餘499;所以對應頁號0,塊號2,實體地址2499
4399/1000=4,餘399,所以對應頁號4,塊號9,實體地址9499
地址變換機構
地址變換機構的任務即把邏輯地址轉換為記憶體中的物理塊號,是藉助頁表完成的,頁表功能是由頁表暫存器來實現的。一個頁表項用一個暫存器。頁表本身是存放在記憶體中的。
快表
- 由於頁表存放於記憶體,CPU在每存取一個數據都需要訪問記憶體兩次
- 先訪問頁表獲取物理塊號,再把其與頁內地址拼接成實體地址
- 訪問實體地址中的資料
-
為了提高地址變換速度,可以在地址變換機構中增設一個具有並行查詢能力的特殊高速緩衝暫存器,即快表(Associative Memory),又稱為聯想暫存器
-
快表用於存放那些當前正在訪問的頁表項。
-
配備快表後,每當需要訪問資料時,首先在快表中尋找是否存在相匹配的頁號,有則直接讀取;否則繼續在記憶體中尋找頁號,並將此頁表項存入快表
-
若快表已滿,則選取一個被認為是不再需要的快表項並替換
訪問記憶體的有效時間
從程序發出訪問邏輯地址的請求開始,經過地址變換,到在記憶體中找到對應的實際實體地址單元並取出資料所花費的總時間即記憶體的有效訪問時間(Effective Access Time,EAT)
設訪問一次記憶體的時間為t,則有效訪問時間等於兩次訪問之和
引入快表前:EAT=t+t=2t
引入快表後:EAT=a×λ+(t+λ)(1−a)+t=2t+λ−t×a
λ表示查詢快表所需時間,a為命中率,t為訪問一次記憶體所需時間
快表雖然減少了一次記憶體訪問,但存在容量限制,所以在快表中查詢所需表項存在命中率的問題
多級頁表
現代作業系統大多支援非常大的邏輯地址空間,頁表隨之變得非常大,要佔用較大記憶體空間。對於頁面大小為4KB的32位邏輯地址,頁表項數最高可達1M,這就意味著對應程序的頁表就會佔用1MB的連續記憶體。
為解決這一問題,對頁表所需記憶體空間採用離散分配方式,只將當前需要的部分頁表項嗲如記憶體,其餘仍駐留在磁碟上
以32位邏輯地址空間為例,當頁面大小為4KB(12位)
若採用一級頁表結構,則具有20位的頁號,頁表項有1M個
若採用兩級頁表結構,則每頁包含2^10(即1024)個頁表項,最多允許1024個頁表分頁,外層頁表中外層頁內地址P2為10位,外層頁號P1也是10位
反置頁表
為了減少頁表佔用的記憶體空間,引入了反置頁表
一般頁表的頁表項是按頁號排序,頁表項內容是物理塊號
反置頁表為每個物理塊設定一個頁表項,並將它們按物理塊的編號排序,內容是頁號和所隸屬程序的識別符號
可利用Hash演算法檢索,但可能出現地址衝突,在檔案系統會進一步介紹
分段儲存管理方式
引入原因
-
方便程式設計
訪問的邏輯地址由段名和段內偏移量決定,方便程式設計,程式直觀
如:
LOAD 1,[A]|<C>
將分段A中C單元讀入暫存器1 -
資訊共享
段是資訊的邏輯單位,避免共享過程佔用多個頁面,簡化實現
-
資訊保護
分段可用更有效地對資訊進行統一保護
-
動態增長
-
動態連結
動態連結的要求是以目標程式(即段)作為連結的基本單位
基本原理
分段
各段從0開始編址且地址空間連續,段長度由相應的邏輯資訊組決定,因此各段的長度很可能各不相同。
段表
與分頁管理類似,分段管理系統也會為每個分段分配一個連續分割槽,併為每個程序建立一張段對映表,即段表。
段表的作用即建立邏輯段到實體記憶體區的對映,每個段在表中都有一個表項,用於記錄段的起始地址以及段的長度。
地址變換機構
為了實現地址變換,同樣也要在系統中設定段表暫存器,用於存放段表起始地址以及段長度
同樣,增設聯想儲存器儲存最近使用的段表項,來提高存取速度
分頁和分段的主要區別
- 頁是資訊的物理單位,其對使用者是不可見的,是系統管理的需要;段是資訊的邏輯單位,為了使用者的需要而劃分
- 頁的大小固定且由系統決定;段的長度不固定且由使用者決定。
- 分頁是系統行為,頁地址空間是線性的,即通過一個邏輯地址就可以計算出對應的實體地址;分段是使用者行為,其地址空間是二維的,即需要提供段號以及段內地址才可以得到實際地址。
段頁式儲存管理方式
將分頁系統和分段系統二者各取所長,形成新的儲存器管理方式
基本原理
- 先把使用者程式分為若干段,併為每個段賦予一個段名,再把每個段分為若干頁。
- 其地址結構由三部分組成:段號、段內頁號、頁內地址。
- 為了實現從邏輯地址到實體地址的轉換,系統中需同時配置段表和頁表。段的內容不再是記憶體起始地址以及段長,而是頁表的起始地址以及頁表長度。
地址變換
- 訪問記憶體中的段表,首先判斷段號是否越界,未越界則利用段表起始地址以及段號求出該段對應項在段表中的位置,從中得出該段的頁表起始地址
- 訪問記憶體中的頁表,利用邏輯地址中的段內頁號獲取對應頁的頁表項所在位置並從中讀取物理塊號,再利用塊號和頁內地址計算實體地址
- 用實體地址從主存獲取資料
在一次資料或指令訪問中,需要訪問三次記憶體。為了提高執行速度,同樣可以設定高速緩衝暫存器。