tags: 操做系統, title: 操做系統第六篇【存儲器管理】程序員
首先,通常的存儲器咱們就會認爲它包含着三部分:算法
所以,咱們的存儲器每每是使用三層結構的。編程
在操做系統的角度而言,咱們面對存儲器就是面對程序的裝入和鏈接安全
通常地**,用戶程序向要在系統上運行,就要經歷下面幾個步驟:**數據結構
用戶程序中使用的地址稱爲相對地址或邏輯地址或虛擬地址。 在早期,當程序裝入內存時,指令存儲在內存中的物理地址與其邏輯地址徹底相同. 這種程序的裝入方式稱爲絕對裝入方式(Absolute Loading Mode)。併發
採用可重定位的裝入方式(Relocation loading Mode)時,若是可以將不一樣的的程序裝入到地址範圍不一樣的物理內存空間,避免分配給各個程序的內存空間疊加(相交或「撞車」),就能實現將多個程序安全裝入內存,使它們共享內存空間,從而支持多任務系統函數
若是使用可重定位裝入方式,就必需要解決:邏輯地址對物理地址之間的轉換性能
靜態連接是由連接器在連接時將庫的內容加入到可執行程序中的作法。 連接器是一個獨立程序,將一個或多個庫或目標文件(先前由編譯器或彙編器生成)連接到一塊生成可執行程序。操作系統
在程序運行前一次性裝入指針
隨着內存技術的發展,爲了讓更多的程序投入有限的內存併發運行,操做系統只將運行程序所必須的模塊裝入內存,其餘諸如幫助系統等不經常使用的程序模塊不裝入內存,進而只裝入可以使程序運行起來的那部分模塊,更加節省了空間。
在程序運行時,分批裝入到內存中
靜態連接是由連接器在連接時將庫的內容加入到可執行程序中的作法。 連接器是一個獨立程序,將一個或多個庫或目標文件(先前由編譯器或彙編器生成)連接到一塊生成可執行程序。
和靜態裝入是同樣的。
載入時動態連接是在將功能模塊讀入內存時把動態庫中調用到的相關模塊的內容載入內存。 載入時動態連接是分別載入,當把一個模塊載入內存時檢查有調用關係的模塊並將其載入內存,比靜態連接節省了許多開銷。 運行時動態連接則是把當前模塊調用的模塊推遲到調用的時候再載入。
在運行時和運行前進行連接。
操做系統將內存分爲系統區和用戶區兩部分
爲了支持多道程序系統和分時系統,支持多個程序併發執行,引入了分區式存儲管理。
分區式存儲管理是把內存分爲一些大小相等或不等的分區,操做系統佔用其中一個分區,其他的分區由應用程序使用,每一個應用程序佔用一個或幾個分區。
1 劃份內存分區的方法
系統對內存的管理和控制經過數據結構—分區說明表進行。 分區說明表說明各分區號、分區大小、起始地址和是不是空閒區(分區狀態)。 內存的分配釋放、存儲保護以及地址變換等都經過分區說明表進行。
內存分區的分配:
若是內存分區的劃分不是預先劃定,而是根據所要運行的程序的大小分配內存,在內存分配階段就不會出現內存碎片。 因而,動態分區技術應運而生。
1 基本問題:
1)動態分區的基本思想:在做業執行前不直接創建分區,分區的創建是在做業的處理過程當中進行的。且其大小可隨做業或進程對內存的要求而改變。 2)動態建立分區:在裝入程序時按其初始要求分配,或在其執行過程當中經過系統調用進行分配或改變分區大小,按需分配。 3)採用的數據結構:內存分配表,由兩個表格組成。一個是已分配區表,另外一張是空閒區表.
動態分區就有兩張表來進行說明了。
動態分區分配內存時從可用表或自由鏈中尋找空閒區的經常使用方法
4)碎片問題
5)碎片問題的解決
動態分區很完美地在內存初次分配階段解決了內存空間浪費的問題。可是,內存是須要重複利用的。 隨着任務的不斷運行完畢,內存空間會被回收;同時,操做系統又會不斷接收新的任務,內存空間會被分配。
因而,當運行一個新任務時,**只能從回收回來的分區上分配內存,一方面動態分區技術在必定程度上退化爲固定分區,**另外一方面分配後餘下的碎片(小塊的內存空間)就被保留了下來,較小的內存空間被分配出去的可能性很小,形成了浪費(碎片)。
最終,內存空間會存在不少小塊的空閒空間,而再也不有大塊的空閒空間,因而當較大型的任務到達時,沒有足夠的空間供分配(儘管這些小塊的空閒內存空間之和比任務所需的空間大)
將碎片合成一大塊---可重定位的動態分區
圖5-10所示爲指令或數據的邏輯地址到物理地址的轉換過程
4 動態重定位分區的分配算法
上面的存儲都是連續的內存分配技術,咱們的分頁存儲是離散的
與其花費巨大的代價搬家,不如離散地存儲在這些碎片中
這就是彙編語言中定義一個段時大小不能夠超過64KB的根本緣由。
離散存儲思想產生的緣由:
離散存儲的基本概念
分頁存儲管理的基本方法
將用戶做業的地址空間分紅若干個大小相同的區域,稱爲頁面或頁,併爲每一個頁從「0」開始編號; 相應地,**主存空間也分紅與頁大小相同的若干個存儲塊,或稱爲物理塊或頁框(frame),**而且採用一樣的方式爲它們進行編號,從0開始:0塊,1塊,…,n-1塊
分頁地址中的地址結構以下:
對某特定機器,其地址結構是必定的。若給定一個邏輯地址空間中的地址爲A,頁面的大小爲L,則頁號P和頁內地址d可按下式求得:
在分頁系統中,容許將進程的各個頁離散地存儲在內存的任一物理塊中,爲保證進程仍然可以正確地運行,即能在內存中找到每一個頁面所對應的物理塊,系統又爲每一個進程創建了一張頁面映像表,簡稱頁表
進程在運行期間,須要對程序和數據的地址進行變換,即將用戶地址空間中的邏輯地址變換爲內存空間中的物理地址,因爲它執行的頻率很是高,每條指令的地址都須要進行變換,所以須要採用硬件來實現。頁表功能是由一組專門的寄存器來實現的。一個頁表項用一個寄存器。
因爲頁表是存放在內存中的,這使CPU在每存取一個數據時,都要兩次訪問內存**。第一次是訪問內存中的頁表,從中找到指定頁的物理塊號,再將塊號與頁內偏移量W拼接,以造成物理地址。第二次訪問內存時,纔是從第一次所得地址中得到所需數據(或向此地址中寫入數據)。**所以,採用這種方式將使計算機的處理速度下降近1/2。可見,以此高昂代價來換取存儲器空間利用率的提升,是得不償失的。
所以,咱們採用:具備快表的地址變換機
用戶把本身的做業按照邏輯關係劃分爲若干個段,每一個段都從0開始編址,並有本身的名字和長度。所以,程序員們都迫切地須要訪問的邏輯地址是由段名(段號)和段內偏移量(段內地址)決定的,這不只能夠方便程序員編程,也可以使程序很是直觀,更具可讀性。
在實現對程序和數據的共享時,是以信息的邏輯單位爲基礎的。
信息保護一樣是以信息的邏輯單位爲基礎的,並且常常是以一個過程、函數或文件爲基本單位進行保護的。
在實際應用中,每每存在着一些段,尤爲是數據段,在它們的使用過程當中,因爲數據量的不斷增長,而使數據段動態增加,相應地它所須要的存儲空間也會動態增長。然而,對於數據段究竟會增加到多大,事先又很難確切地知道。對此,很難採起預先多分配的方法進行解決。
在分段存儲管理方式中,做業的地址空間被劃分爲若干個段,每一個段定義了一組邏輯信息。例如,有主程序段MAIN、子程序段X、數據段D及堆棧段S等。
在前面所介紹的動態分區分配方式中,系統爲整個進程分配一個連續的內存空間。而在分段式存儲管理系統中,則是爲每一個分段分配一個連續的分區。進程中的各個段,能夠離散地裝入內存中不一樣的分區中。爲保證程序能正常運行,就必須能從物理內存中找出每一個邏輯段所對應的位置。這就須要段表了
爲了實現進程從邏輯地址到物理地址的變換功能,**在系統中設置了段表寄存器,用於存放段表始址和段表長度TL。**在進行地址變換時,系統將邏輯地址中的段號與段表長度TL進行比較。若S>TL,表示段號太大,是訪問越界,因而產生越界中斷信號。若未越界,則根據段表的始址和該段的段號,計算出該段對應段表項的位置,從中讀出該段在內存的起始地址。而後,再檢查段內地址d是否超過該段的段長SL。若超過,即d>SL,一樣發出越界中斷信號。若未越界,則將該段的基址d與段內地址相加,便可獲得要訪問的內存物理地址。圖示出了分段系統的地址變換過程。
(1)頁是信息的物理單位,分頁是爲了實現離散的分配方式,以消減主存「碎片」,提升主存的利用率。或者說,分頁僅僅是因爲系統管理的須要,而不是用戶的須要。段是信息的邏輯單位,它包含一組意義相對完整的信息。分段的目的是爲了能更好地知足用戶的須要。 (2)頁的大小固定且由系統肯定,把邏輯地址劃分爲頁號和頁內地址兩部分,是由機器硬件實現的,於是一個系統只能有一種大小的頁面。段的長度卻不固定,決定於用戶所編寫的程序,一般由編譯程序在對源程序進行編譯時,根據信息的性質來劃分。 (3)分頁的做業地址空間是一維的,即單一的線性地址空間,程序員只須要利用一個記憶符,便可表示一個地址。分段的做業地址空間是二維的,程序員在標識一個地址時,既需給出段名,又需給出段內地址。
段頁式系統的基本原理是分段和分頁原理的結合,即先將用戶程序分紅若干個段,再把每一個段分紅若干個頁,併爲每個段賦予一個段名。圖(a)示出了一個做業地址空間的結構。該做業有三個段:主程序段、子程序段和數據段;頁面大小爲 4 KB。在段頁式系統中,其地址結構由段號、段內頁號及頁內地址三部分所組成,如圖(b)所示。
在段頁式系統中,爲了實現從邏輯地址到物理地址的變換,系統中須要同時配置段表和頁表。段表的內容與分段系統略有不一樣,它再也不是內存始址和段長,而是頁表始址和頁表長度。圖示出了利用段表和頁表進行從用戶地址空間到物理(內存)空間的映射。
地址變換過程:
在段頁式系統中,爲了便於實現地址變換,須配置一個段表寄存器,其中存放段表始址和段長TL。進行地址變換時,首先利用段號S,將它與段長TL進行比較。若S < TL,表示未越界,因而利用段表始址和段號來求出該段所對應的段表項在段表中的位置,從中獲得該段的頁表始址,並利用邏輯地址中的段內頁號P來得到對應頁的頁表項位置,從中讀出該頁所在的物理塊號b,再利用塊號b和頁內地址來構成物理地址。圖示出了段頁式系統中的地址變換機構。
要求將一個做業所有裝入內存後方能運行,因而,出現了下面這樣兩種狀況:
局部性原理:
基於局部性原理可知,應用程序在運行以前沒有必要將之所有裝入內存,而僅須將那些當前要運行的少數頁面或段先裝入內存即可運行,其他部分暫留在盤上。
當用戶看到本身的程序能在系統中正常運行時,他會認爲,該系統所具備的內存容量必定比本身的程序大,或者說,用戶所感受到的內存容量會比實際內存容量大得多。但用戶所看到的大容量只是一種錯覺,是虛的,故人們把這樣的存儲器稱爲虛擬存儲器。
主要的硬件支持有:
爲了實現請求分頁,系統必須提供必定的硬件支持。計算機系統除了要求必定容量的內存和外存外,還須要有請求頁表機制、缺頁中斷機構以及地址變換機構。
在請求分頁系統中須要的主要數據結構是請求頁表,其基本做用仍然是將用戶地址空間中的邏輯地址映射爲內存空間中的物理地址。爲了知足頁面換進換出的須要,在請求頁表中又增長了四個字段。這樣,在請求分頁系統中的每一個頁表應含如下諸項
一個顯而易見的事實是,隨着爲每一個進程所分配的物理塊的減小,將使進程在執行中的缺頁率上升,從而會下降進程的執行速度。最小物理塊數是指能保證進程正常運行所需的最小物理塊數,當系統爲進程分配的物理塊數少於此值時,進程將沒法運行。
考慮優先權的分配算法。在實際應用中,爲了照顧到重要的、緊迫的做業能儘快地完成,應爲它分配較多的內存空間。**一般採起的方法是把內存中可供分配的全部物理塊分紅兩部分:一部分按比例地分配給各進程;另外一部分則根據各進程的優先權進行分配,爲高優先進程適當地增長其相應份額。**在有的系統中,如重要的實時控制系統,則多是徹底按優先權爲各進程分配其物理塊的。
爲使進程可以正常運行,必須事先將要執行的那部分程序和數據所在的頁面調入內存。如今的問題是:
事實上,在缺頁中斷處理時,當因爲空間不足,須要置換部分頁面到外存時,選擇被置換頁面還須要考慮到置換的代價,如頁面是否被修改過。沒有修改過的頁面能夠直接放棄,而修改過的頁面則必須進行保存,因此處理這兩種狀況時的時間也是不一樣的。假設被置換的頁面被修改的機率是β,其缺頁中斷處理時間爲ta,被置換頁面沒有被修改的缺頁中斷時間爲tb,那麼,缺頁中斷處理時間的計算公式爲 t=β×ta+(1—β)×tb
在進程運行過程當中,若其所要訪問的頁面不在內存,而需把它們調入內存,但內存已無空閒空間時,爲了保證該進程能正常運行,系統必須從內存中調出一頁程序或數據送到磁盤的對換區中。但應將哪一個頁面調出,須根據必定的算法來肯定。一般,把選擇換出頁面的算法稱爲頁面置換算法(Page-Replacement Algorithms)。置換算法的好壞將直接影響到系統的性能。
最佳置換算法是由Belady於1966年提出的一種理論上的算法。其所選擇的被淘汰頁面將是之後永不使用的,或許是在最長(將來)時間內再也不被訪問的頁面。採用最佳置換算法一般可保證得到最低的缺頁率。但因爲人們目前還沒法預知,一個進程在內存的若干個頁面中,哪個頁面是將來最長時間內再也不被訪問的,於是該算法是沒法實現的,但能夠利用該算法去評價其它算法。
該算法是沒法實現的,可是會利用該算法去評價其它算法。
FIFO算法是最先出現的置換算法。該算法老是淘汰最早進入內存的頁面,即選擇在內存中駐留時間最久的頁面予以淘汰。該算法實現簡單,只需把一個進程已調入內存的頁面按前後次序連接成一個隊列,並設置一個指針,稱爲替換指針,使它老是指向最老的頁面。但該**算法與進程實際運行的規律不相適應,**由於在進程中,有些頁面常常被訪問,好比,含有全局變量、經常使用函數、例程等的頁面,FIFO算法並不能保證這些頁面不被淘汰。
淘汰最早進入內存的頁面,但可能那些頁面也會被再次使用。因此這個算法也不太行。
FIFO置換算法的性能之因此較差,是由於它所依據的條件是各個頁面調入內存的時間,而頁面調入的前後並不能反映頁面的使用狀況。最近最久未使用(LRU)的頁面置換算法是根據頁面調入內存後的使用狀況作出決策的。
須要的硬件支持:
可利用一個特殊的棧保存當前使用的各個頁面的頁面號。每當進程訪問某頁面時,便將該頁面的頁面號從棧中移出,將它壓入棧頂。所以,棧頂始終是最新被訪問頁面的編號,而棧底則是最近最久未使用頁面的頁面號。假定現有一進程,它分有五個物理塊,所訪問的頁面的頁面號序列爲:4,7,0,7,1,0,1,2,1,2,6
「抖動」與工做集 :
因爲請求分頁式虛擬存儲器系統的性能優越,在正常運行狀況下,它能有效地減小內存碎片,提升處理機的利用率和吞吐量,故是目前最經常使用的一種系統。但若是在系統中運行的進程太多,進程在運行中會頻繁地發生缺頁狀況,這又會對系統的性能產生很大的影響,故還須對請求分頁系統的性能作簡單的分析。
因爲虛擬存儲器系統能從邏輯上擴大內存,這時,只需裝入一個進程的部分程序和數據即可開始運行,故人們但願在系統中能運行更多的進程,即增長多道程序度,以提升處理機的利用率。**但處理機的實際利用率卻如圖中的實線所示。 **
產生「抖動」的緣由:
發生「抖動」的根本緣由是,同時在系統中運行的進程太多,由此分配給每個進程的物理塊太少,不能知足進程正常運行的基本要求,導致每一個進程在運行時,頻繁地出現缺頁,必須請求系統將所缺之頁調入內存。這會使得在系統中排隊等待頁面調進/調出的進程數目增長。顯然,對磁盤的有效訪問時間也隨之急劇增長,形成每一個進程的大部分時間都用於頁面的換進/換出,而幾乎不能再去作任何有效的工做,從而致使發生處理機的利用率急劇降低並趨於0的狀況。咱們稱此時的進程是處於「抖動」狀態。
若是您以爲這篇文章幫助到了您,能夠給做者一點鼓勵