計算存儲的層次結構:程序員
當前技術沒有可以提供這樣的存儲器,所以大部分的計算機都有一個存儲器層次結構,即少許的很是快速、昂貴、易變的高速緩存(cache);若干兆字節的中等速度、中等價格、易變的主存儲器(RAM);數百兆或數千兆的低速、廉價、不易變的磁盤。這些資源的合理使用與否直接關係着系統的效率。 算法
1. 內存管理方法編程
內存管理主要包括虛地址、地址變換、內存分配和回收、內存擴充、內存共享和保護等功能。 緩存
2. 連續分配存儲管理方式數據結構
連續分配是指爲一個用戶程序分配連續的內存空間。連續分配有單一連續存儲管理和分區式儲管理兩種方式。併發
在這種管理方式中,內存被分爲兩個區域:系統區和用戶區。應用程序裝入到用戶區,可以使用用戶區所有空間。其特色是,最簡單,適用於單用戶、單任務的操做系統。CP/M和 DOS 2.0如下就是採用此種方式。這種方式的最大優勢就是易於管理。但也存在着一些問題和不足之處,例如對要求內存空間少的程序,形成內存浪費;程序所有裝入,使得不多使用的程序部分也佔用—定數量的內存。app
爲了支持多道程序系統和分時系統,支持多個程序併發執行,引入了分區式存儲管理。分區式存儲管理是把內存分爲一些大小相等或不等的分區,操做系統佔用其中一個分區,其他的分區由應用程序使用,每一個應用程序佔用一個或幾個分區。分區式存儲管理雖然能夠支持併發,但難以進行內存分區的共享。ide
分區式存儲管理引人了兩個新的問題:內碎片和外碎片。函數
內碎片是佔用分區內未被利用的空間,外碎片是佔用分區之間難以利用的空閒分區(一般是小空閒分區)。性能
爲實現分區式存儲管理,操做系統應維護的數據結構爲分區表或分區鏈表。表中各表項通常包括每一個分區的起始地址、大小及狀態(是否已分配)。
分區式存儲管理常採用的一項技術就是內存緊縮(compaction)。
固定式分區的特色是把內存劃分爲若干個固定大小的連續分區。分區大小能夠相等:這種做法只適合於多個相同程序的併發執行(處理多個類型相同的對象)。分區大小也能夠不等:有多個小分區、適量的中等分區以及少許的大分區。根據程序的大小,分配當前空閒的、適當大小的分區。
優勢:易於實現,開銷小。
缺點主要有兩個:內碎片形成浪費;分區總數固定,限制了併發執行的程序數目。
動態分區的特色是動態建立分區:在裝入程序時按其初始要求分配,或在其執行過程當中經過系統調用進行分配或改變分區大小。與固定分區相比較其優勢是:沒有內碎片。但它卻引入了另外一種碎片——外碎片。動態分區的分區分配就是尋找某個空閒分區,其大小需大於或等於程序的要求。如果大於要求,則將該分區分割成兩個分區,其中一個分區爲要求的大小並標記爲「佔用」,而另外一個分區爲餘下部分並標記爲「空閒」。分區分配的前後次序一般是從內存低端到高端。動態分區的分區釋放過程當中有一個要注意的問題是,將相鄰的空閒分區合併成一個大的空閒分區。
下面列出了幾種經常使用的分區分配算法:
最早適配法(nrst-fit):按分區在內存的前後次序從頭查找,找到符合要求的第一個分區進行分配。該算法的分配和釋放的時間性能較好,較大的空閒分區能夠被保留在內存高端。但隨着低端分區不斷劃分會產生較多小分區,每次分配時查找時間開銷便會增大。
下次適配法(循環首次適應算法 next fit):按分區在內存的前後次序,從上次分配的分區起查找(到最後{區時再從頭開始},找到符合要求的第一個分區進行分配。該算法的分配和釋放的時間性能較好,使空閒分區分佈得更均勻,但較大空閒分區不易保留。
最佳適配法(best-fit):按分區在內存的前後次序從頭查找,找到其大小與要求相差最小的空閒分區進行分配。從個別來看,外碎片較小;但從總體來看,會造成較多外碎片優勢是較大的空閒分區能夠被保留。
最壞適配法(worst- fit):按分區在內存的前後次序從頭查找,找到最大的空閒分區進行分配。基本不留下小空閒分區,不易造成外碎片。但因爲較大的空閒分區不被保留,當對內存需求較大的進程須要運行時,其要求不易被知足。
固定分區和動態分區方式都有不足之處。固定分區方式限制了活動進程的數目,當進程大小與空閒分區大小不匹配時,內存空間利用率很低。動態分區方式算法複雜,回收空閒分區時須要進行分區合併等,系統開銷較大。夥伴系統方式是對以上兩種內存方式的一種折衷方案。
夥伴系統規定,不管已分配分區或空閒分區,其大小均爲 2 的 k 次冪,k 爲整數, l≤k≤m,其中:
2^1 表示分配的最小分區的大小,
2^m 表示分配的最大分區的大小,
一般 2^m是整個可分配內存的大小。
假設系統的可利用空間容量爲2^m個字, 則系統開始運行時, 整個內存區是一個大小爲2^m的空閒分區。在系統運行過中, 因爲不斷的劃分,可能會造成若干個不連續的空閒分區,將這些空閒分區根據分區的大小進行分類,對於每一類具備相同大小的全部空閒分區,單獨設立一個空閒分區雙向鏈表。這樣,不一樣大小的空閒分區造成了k(0≤k≤m)個空閒分區鏈表。
分配步驟:
當須要爲進程分配一個長度爲n 的存儲空間時:
首先計算一個i 值,使 2^(i-1) <n ≤ 2^i,
而後在空閒分區大小爲2^i的空閒分區鏈表中查找。
若找到,即把該空閒分區分配給進程。
不然,代表長度爲2^i的空閒分區已經耗盡,則在分區大小爲2^(i+1)的空閒分區鏈表中尋找。
若存在 2^(i+1)的一個空閒分區,則把該空閒分區分爲相等的兩個分區,這兩個分區稱爲一對夥伴,其中的一個分區用於配, 而把另外一個加入分區大小爲2^i的空閒分區鏈表中。
若大小爲2^(i+1)的空閒分區也不存在,則須要查找大小爲2^(i+2)的空閒分區, 若找到則對其進行兩次分割:
第一次,將其分割爲大小爲 2^(i+1)的兩個分區,一個用於分配,一個加入到大小爲 2^(i+1)的空閒分區鏈表中;
第二次,將第一次用於分配的空閒區分割爲 2^i的兩個分區,一個用於分配,一個加入到大小爲 2^i的空閒分區鏈表中。
若仍然找不到,則繼續查找大小爲 2^(i+3)的空閒分區,以此類推。
因而可知,在最壞的狀況下,可能須要對 2^k的空閒分區進行 k 次分割才能獲得所需分區。
與一次分配可能要進行屢次分割同樣,一次回收也可能要進行屢次合併,如回收大小爲2^i的空閒分區時,若事先已存在2^i的空閒分區時,則應將其與夥伴分區合併爲大小爲2^i+1的空閒分區,若事先已存在2^i+1的空閒分區時,又應繼續與其夥伴分區合併爲大小爲2^i+2的空閒分區,依此類推。
在夥伴系統中,其分配和回收的時間性能取決於查找空閒分區的位置和分割、合併空閒分區所花費的時間。與前面所述的多種方法相比較,因爲該算法在回收空閒分區時,須要對空閒分區進行合併,因此其時間性能比前面所述的分類搜索算法差,但比順序搜索算法好,而其空間性能則遠優於前面所述的分類搜索法,比順序搜索法略差。 須要指出的是,在當前的操做系統中,廣泛採用的是下面將要講述的基於分頁和分段機制的虛擬內存機制,該機制較夥伴算法更爲合理和高效,但在多處理機系統中,夥伴系統仍不失爲一種有效的內存分配和釋放的方法,獲得了大量的應用。
內存緊縮:將各個佔用分區向內存一端移動,而後將各個空閒分區合併成爲一個空閒分區。
這種技術在提供了某種程度上的靈活性的同時,也存在着一些弊端,例如:對佔用分區進行內存數據搬移佔用CPU時間;若是對佔用分區中的程序進行「浮動」,則其重定位須要硬件支持。
圖8.12
堆結構的存儲管理的分配算法:
在動態存儲過程當中,無論哪一個時刻,可利用空間都是-一個地址連續的存儲區,在編譯程序中稱之爲"堆",每次分配都是從這個可利用空間中劃出一塊。其實現辦法是:設立一個指針,稱之爲堆指針,始終指向堆的最低(或鍛聯)地址。當用戶申請N個單位的存儲塊時,堆指針向高地址(或 低地址)稱動N個存儲單位,而移動以前的堆指針的值就是分配給用戶的佔用塊的初始地址。例如,某個串處理系統中有A、B、C、D這4個串,其串值長度分別為12,6,10和8. 假設堆指針free的初值爲零,則分配給這4個串值的存儲空間的初始地址分別爲0.12.18和 28,如圖8.12(a)和(b)所示,分配後的堆指針的值爲36。 所以,這種堆結構的存儲管理的分配算法很是簡單,
釋放內存空間執行內存緊縮:
回收用戶釋放的空閒塊就比較麻煩.因爲系統的可利用空間始終是一個絕址連續的存儲塊,所以回收時必須將所釋放的空間塊合併到整個堆上去才 能從新使用,這就是"存儲策縮"的任務.一般,有兩種作法:
一種是一旦有用戶釋放存儲塊即進行回收緊縮,例始,圖8.12 (a)的堆,在c串釋放存儲塊時即回收緊縮,例如圖8.12 (c)的堆,同時修改串的存儲映像成圖8.12(d)的狀態;
另外一種是在程序執行過程當中不回收用戶隨時釋放的存儲塊,直到可利用空同不夠分配或堆指針指向最高地址時才進行存儲緊縮。此時緊縮的目的是將堆中全部的空間塊連成一塊,即將全部的佔用塊部集中到 可利用空間的低地地區,而剩餘的高地址區成爲一整個地繼連續的空閒塊,如圖8.13所示,其中(a)爲緊縮前的狀態,(b)爲緊縮後的狀態•
圖8.13 a 緊縮前 b緊縮後
和無用單元收集相似,爲實現存儲紫編,首先要對佔用塊進行「標誌」,標誌算法和無用單元收集類同(存儲塊的結構可能不一樣),其次需進行下列4步雄做:
(1)計算佔用塊的新地址。從最低地址開始巡査整個存儲空間,對每個佔用塊找到它在緊縮後的新地址。 爲此,需設立兩個指針隨巡查向前移動,這兩個指針分別指示佔用 塊在緊縮以前和以後的原地址和新地址。所以,在每一個佔用塊的第-·個存儲單位中,除了 設立長度域(存儲該佔用換的大小)和標誌域(存儲區別該存儲塊是佔用塊或空閒塊的標 志)以外,還需設立一個新地址城,以存儲佔用塊在緊縮後應有的新地址,即創建一張新, 舊地址的對照表m
(2)修改用戶觸初始變量表,以便在存儲緊縮後用戶程序能繼續正常運行*。
(3)檢查每一個佔用塊中存儲的數據, 如有指向其餘存儲換的指針,則需做相應修改.
(4)將全部佔用塊遷移到新地址走,這實質上是做傳送數據的工做。
至此,完成了存儲緊縮的操做,最後,將堆指針賦以新值(即緊縮後的空閒存儲區的最低地址)。
可見,存儲緊縮法比無用單元收集法更爲複雜,前者不只要傳送數據(進行佔用塊遷移),並且還有須要修改全部佔用塊中的指針值。所以,存儲緊縮也是個系統操做,且非不得已就不用。
3. 覆蓋和交換技術
引入覆蓋 (overlay)技術的目標是在較小的可用內存中運行較大的程序。這種技術經常使用於多道程序系統之中,與分區式存儲管理配合使用。
覆蓋技術的原理:一個程序的幾個代碼段或數據段,按照時間前後來佔用公共的內存空間。將程序必要部分(經常使用功能)的代碼和數據常駐內存;可選部分(不經常使用功能)平時存放在外存(覆蓋文件)中,在須要時才裝入內存。不存在調用關係的模塊沒必要同時裝入到內存,從而能夠相互覆蓋。
在任什麼時候候只在內存中保留所需的指令和數據;當須要其它指令時,它們會裝入到剛剛再也不須要的指令所佔用的內存空間;
如在同一時刻,CPU只能執行B,C中某一條。B,C之間就能夠作覆蓋。
覆蓋技術的缺點是編程時必須劃分程序模塊和肯定程序模塊之間的覆蓋關係,增長編程複雜度;從外存裝入覆蓋文件,以時間延長換取空間節省。
覆蓋的實現方式有兩種:以函數庫方式實現或操做系統支持。
交換 (swapping)技術在多個程序併發執行時,能夠將暫時不能執行的程序(進程)送到外存中,從而得到空閒內存空間來裝入新程序(進程),或讀人保存在外存中而處於就緒狀態的程序。交換單位爲整個進程的地址空間。交換技術經常使用於多道程序系統或小型分時系統中,由於這些系統大多采用分區存儲管理方式。與分區式存儲管理配合使用又稱做「對換」或「滾進/滾出」 (roll-in/roll-out)。
交換技術優勢之一是增長併發運行的程序數目,並給用戶提供適當的響應時間;與覆蓋技術相比交換技術另外一個顯著的優勢是不影響程序結構。交換技術自己也存在着不足,例如:對換人和換出的控制增長處理器開銷;程序整個地址空間都進行對換,沒有考慮執行過程當中地址訪問的統計特性。
1)與覆蓋技術相比,交換不要求程序員給出程序段之間的覆蓋結構。
2)交換主要是在進程與做業之間進行,而覆蓋則主要在同一做業或進程內進行。 另外覆蓋只能覆蓋那些與覆蓋程序段無關的程序段。
4. 頁式和段式存儲管理
在前面的幾種存儲管理方法中,爲進程分配的空間是連續的,使用的地址都是物理地址。若是容許將一個進程分散到許多不連續的空間,就能夠避免內存緊縮,減小碎片。基於這一思想,經過引入進程的邏輯地址,把進程地址空間與實際存儲空間分離,增長存儲管理的靈活性。地址空間和存儲空間兩個基本概念的定義以下:
地址空間:將源程序通過編譯後獲得的目標程序,存在於它所限定的地址範圍內,這個範圍稱爲地址空間。地址空間是邏輯地址的集合。
存儲空間:指主存中一系列存儲信息的物理單元的集合,這些單元的編號稱爲物理地址存儲空間是物理地址的集合。
根據分配時所採用的基本單位不一樣,可將離散分配的管理方式分爲如下三種:
頁式存儲管理、段式存儲管理和段頁式存儲管理。其中段頁式存儲管理是前兩種結合的產物。
5. 頁式存儲管理
將程序的邏輯地址空間劃分爲固定大小的頁(page),而物理內存劃分爲一樣大小的頁框(page frame)。程序加載時,可將任意一頁放人內存中任意一個頁框,這些頁框沒必要連續,從而實現了離散分配。該方法須要CPU的硬件支持,來實現邏輯地址和物理地址之間的映射。在頁式存儲管理方式中地址結構由兩部構成,前一部分是頁號,後一部分爲頁內地址w(位移量),如圖4所示:
頁式管理方式的優勢是:
1)沒有外碎片,每一個內碎片不超過頁大比前面所討論的幾種管理方式的最大進步是,
2)一個程序沒必要連續存放。
3)便於改變程序佔用空間的大小(主要指隨着程序運行,動態生成的數據增多,所要求的地址空間相應增加)。
缺點是:要求程序所有裝入內存,沒有足夠的內存,程序就不能執行。
在頁式系統中進程創建時,操做系統爲進程中全部的頁分配頁框。當進程撤銷時收回全部分配給它的頁框。在程序的運行期間,若是容許進程動態地申請空間,操做系統還要爲進程申請的空間分配物理頁框。操做系統爲了完成這些功能,必須記錄系統內存中實際的頁框使用狀況。操做系統還要在進程切換時,正確地切換兩個不一樣的進程地址空間到物理內存空間的映射。這就要求操做系統要記錄每一個進程頁表的相關信息。爲了完成上述的功能,—個頁式系統中,通常要採用以下的數據結構。
進程頁表:完成邏輯頁號(本進程的地址空間)到物理頁面號(實際內存空間,也叫塊號)的映射。
每一個進程有一個頁表,描述該進程佔用的物理頁面及邏輯排列順序,如圖:
圖4-1 頁表
物理頁面表:整個系統有一個物理頁面表,描述物理內存空間的分配使用情況,其數據結構可採用位示圖和空閒頁鏈表。
對於位示圖法,即若是該頁面已被分配,則對應比特位置1,否置0.
圖4-2 頁面表
請求表:整個系統有一個請求表,描述系統內各個進程頁表的位置和大小,用於地址轉換也能夠結合到各進程的PCB(進程控制塊)裏。如圖:
圖4-3 請求表
在頁式系統中,指令所給出的地址分爲兩部分:邏輯頁號和頁內地址。
上述過程一般由處理器的硬件直接完成,不須要軟件參與。一般,操做系統只需在進程切換時,把進程頁表的首地址裝入處理器特定的寄存器中便可。通常來講,頁表存儲在主存之中。這樣處理器每訪問一個在內存中的操做數,就要訪問兩次內存:
第一次用來查找頁表將操做數的 邏輯地址變換爲物理地址;
第二次完成真正的讀寫操做。
這樣作時間上耗費嚴重。爲縮短查找時間,能夠將頁表從內存裝入CPU內部的關聯存儲器(例如,快表) 中,實現按內容查找。此時的地址變換過程是:在CPU給出有效地址後,由地址變換機構自動將頁號送人快表,並將此頁號與快表中的全部頁號進行比較,並且這 種比較是同時進行的。若其中有與此相匹配的頁號,表示要訪問的頁的頁表項在快表中。因而可直接讀出該頁所對應的物理頁號,這樣就無需訪問內存中的頁表。因爲關聯存儲器的訪問速度比內存的訪問速度快得多。
5. 段式存儲管理
在段式存儲管理中,將程序的地址空間劃分爲若干個段(segment),這樣每一個進程有一個二維的地址空間。在前面所介紹的動態分區分配方式中,系統爲整個進程分配一個連續的內存空間。而在段式存儲管理系統中,則爲每一個段分配一個連續的分區,而進程中的各個段能夠不連續地存放在內存的不一樣分區中。程序加載時,操做系統爲全部段分配其所需內存,這些段沒必要連續,物理內存的管理採用動態分區的管理方法。
在爲某個段分配物理內存時,能夠採用首先適配法、下次適配法、最佳適配法等方法。
在回收某個段所佔用的空間時,要注意將收回的空間與其相鄰的空間合併。
段式存儲管理也須要硬件支持,實現邏輯地址到物理地址的映射。
程序經過分段劃分爲多個模塊,如代碼段、數據段、共享段:
這樣作的優勢是:能夠分別編寫和編譯源程序的一個文件,而且能夠針對不一樣類型的段採起不一樣的保護,也能夠按段爲單位來進行共享。
總的來講,段式存儲管理的優勢是:沒有內碎片,外碎片能夠經過內存緊縮來消除;便於實現內存共享。缺點與頁式存儲管理的缺點相同,進程必須所有裝入內存。
爲了實現段式管理,操做系統須要以下的數據結構來實現進程的地址空間到物理內存空間的映射,並跟蹤物理內存的使用狀況,以便在裝入新的段的時候,合理地分配內存空間。
·進程段表:描述組成進程地址空間的各段,能夠是指向系統段表中表項的索引。每段有段基址(baseaddress),即段內地址。
在系統中爲每一個進程創建一張段映射表,如圖:
·系統段表:系統全部佔用段(已經分配的段)。
·空閒段表:內存中全部空閒段,能夠結合到系統段表中。
圖4—5 段式管理的地址變換
在段式 管理系統中,整個進程的地址空間是二維的,即其邏輯地址由段號和段內地址兩部分組成。爲了完成進程邏輯地址到物理地址的映射,處理器會查找內存中的段表,由段號獲得段的首地址,加上段內地址,獲得實際的物理地址(見圖4—5)。這個過程也是由處理器的硬件直接完成的,操做系統只需在進程切換時,將進程段表的首地址裝入處理器的特定寄存器當中。這個寄存器通常被稱做段表地址寄存器。
6. 頁式和段式管理的區別
頁式和段式系統有許多類似之處。好比,二者都採用離散分配方式,且都經過地址映射機構來實現地址變換。但概念上二者也有不少區別,主要表如今:
1)、需求:是信息的物理單位,分頁是爲了實現離散分配方式,以減小內存的碎片,提升內存的利用率。或者說,分頁僅僅是因爲系統管理的須要,而不是用戶的須要。段是信息的邏輯單位,它含有一組其意義相對完整的信息。分段的目的是爲了更好地知足用戶的須要。
2)、大小:頁大小固定且由系統決定,把邏輯地址劃分爲頁號和頁內地址兩部分,是由機器硬件實現的。段的長度不固定,且決定於用戶所編寫的程序,一般由編譯系統在對源程序進行編譯時根據信息的性質來劃分。
3)、邏輯地址表示:頁式系統地址空間是一維的,即單一的線性地址空間,程序員只需利用一個標識符,便可表示一個地址。分段的做業地址空間是二維的,程序員在標識一個地址時,既需給出段名,又需給出段內地址。
4)、比頁大,於是段表比頁表短,能夠縮短查找時間,提升訪問速度。