內存管理之非連續分配管理方式的詳細解釋

 

如果幫到你的話,請點個贊,創作不易,謝謝

 

  非連續分配方式允許將一個程序分散地裝入不連續的內存空間。在連續分配管理方式中,即使內存有超過2GB的存儲空間,但是沒有連續的2GB內存空間,則需要2GB內存空間的作業仍然無法裝入內存運行。但若採用連續分配管理方式,則可以將該 作業所要求的2GB空間不連續地分配到在內存的各個區域,所以,這也需要額外的內存空間來存放這些索引,使得非連續分配管理方式的存儲密度低於連續分配存儲管理方式。

非連續分配管理方式根據分區的大小是否固定分爲分頁存儲管理方式和分段存儲管理方式。

分頁存儲管理方式中,根據作業運行時是否需要把作業的所有頁面都裝入內存才能運行分爲基本分頁存儲管理方式和請求分頁存儲管理方式。

  1. 基本分頁管理方式

       固定分區會產生內部碎片,動態分區會產生外部碎片,這樣都會浪費內存空間,使內存效率降低。所以,我們要在內存使用時儘量減少內存碎片的產生 ,這就引入了分頁的思想:把內存空間劃分爲大小相同且固定的塊,塊相對較小,作爲內存的基本單位。每個進程以塊爲單位進行劃分,進程在執行時,以塊爲單位逐個申請內存中的塊空間。

       分頁的方法從形式上看,類似分區相等的固定分區分配技術,分頁管理不會產生外部碎片,但它的不同點爲:快的大小要小很多,而且進程也按照塊進行劃分,進程運行時按塊申請內存可用空間並執行。這樣,進程只會在爲最後一個不完整的塊申請內存塊空間時,纔會產生內存碎片。所以儘管會產生內部碎片,但對於進程來說也是很小的。每個進程平均只產生半個快大小的內部碎片。(也稱業內碎片)

(1)分頁存儲管理的幾個基本概念

① 頁面和頁面大小。進程中的塊稱爲頁,內存中的塊稱爲頁框(Page Frame,或頁幀)。外存也以同樣的單位進行劃分,直接稱爲塊(Block)。進程在執行時需要申請內存空間,即需要爲每個頁面分配每個可用的頁框,這就需要頁和頁框一一對應。

    爲了方便地址轉換,頁面大小應該是2的整數冪。同時頁面大小要適中,頁面太小會使進程有太多的頁面,這樣頁表就會過長,佔用大量內存,增加硬件地址轉換的開銷,而且也會使頁面換入/換出的效率降低(頻繁的換入換出)。頁面過大又會使頁內碎片增多,造成內存的利用率降低。所以,頁面的大小應該適中,要在時間效率和空間效率之間找到平衡。

② 地址結構

31       ...                                                12       11                   0
頁號P 頁內偏移量W

                                                                              分頁存儲管理的邏輯結構

 地址結構包含兩部分:前一部分爲頁號P,後一部分爲頁內偏移量。地址長度爲32位,其中0~11位爲頁內地址,即每頁爲4kb,12~31位爲頁號,即地址空間最多有2^20頁。

  • 地址空間結構決定了虛擬內存的尋址空間有多大。

 ③ 頁表

爲了便於在內存中找到進程的每個頁面所對應的物理塊,系統爲每個進程建立一張頁表,它記錄頁面在內存中的物理快號,頁表一般放在內存中。

頁表是由頁表項組成的,頁表和地址都由兩部分構成,而且第一部分都是頁號,頁表的第二部分是物理內存中的塊號,而地址的第二部分是頁內偏移,頁表項的第二部分與地址的第二部分共同構成物理地址。

在配置頁表後,進程在執行時,通過查找該表,即可找到每頁在內存中的物理塊號,由此可見,快表的作用是實現進程的頁號到物理塊號的地址映射。

(2)基本地址變換機構

 地址變換機構是將邏輯地址轉換爲內存中的物理地址,地址變換是藉助於頁表實現的。

å¨è¿éæå¥å¾çæè¿°

 

  在系統中通常設置一個頁表寄存器(PTR),存放頁表在內存的始址F和頁表長度M。進程未執行時,頁表的始址和頁表長度都存放在進程控制塊中,當進程執行時,纔將始址和頁表長度放入頁表寄存器。

設頁面大小爲L,從邏輯地址A到物理地址E 的地址變換過程如下(邏輯地址,頁號,頁表項長度都是十進制數):

① 計算頁號P(P=A/L)和頁內偏移量W(W=A%L)

②比較頁號P和頁表長度M,若P≥M,則發生越界中斷,否則拒絕執行。

③頁表中頁號P對應的頁表項地址=頁表始址+頁號P×頁表項長度,取出該頁表項的內容b,即爲物理塊號,注意區分頁表長度和頁表項長度,頁表長度指的是一共有多少頁,頁表項長度指的是頁地址佔多大的存儲空間。

④計算E=b+W,用得到的物理地址E去訪問內存

上面的整個地址變換過程都是由硬件地址變換機構實現的。例如å¨è¿éæå¥å¾çæè¿°

 因爲頁面大小L是固定的,因此,頁式管理中地址空間是一維的。

  • 頁表項的大小是受約束的,不是隨意規定的,是可以計算出來的,如何確定頁表項的大小呢?

   頁表項的作用是找到該頁在內存中的位置。以32位邏輯地址空間,字節編址單位,一頁4KB爲例,地址空間內一共有2^32B/4KB =2^20=1M頁,因此需要log以2爲底對數爲1M=20位才能保證範圍能容納所有頁面,又因爲以字節作爲編址單位,即頁表項的大小≥「20/8](不會打右邊的上取整符號了)=3B.所以,爲了保證頁表能夠指向所有頁面,頁表項的大小應該>3B,當然,也可以選擇更大的頁表項讓一個頁面能夠剛好容下所有頁表項,進而方便存儲(如果取成4B,剛還一個頁面可以裝下4KB/4B=1k個頁表項)或增加一些其它信息。

分頁管理存儲方式存在兩個主要問題:

①每次訪存操作都需要進行邏輯地址到物理地址的轉換,地址轉換過程必須足夠快,否則訪存速度會降低。

②每個進程都要進入頁表,爲了存儲索引(即映射機制),頁表不能太大,否則會造成內存空間的浪費。

 (3) 具有快表的地址變換機構

           若頁表全部放在內存中,則存取一個數據或一條指令至少需要訪問兩次內存:第一次是訪問頁表,根據頁表的內容計算所存取的數據或指令的物理地址;第二次是根據該物理地址再次進入內存去存數據或指令。顯然,這種方法比通常執行指令的速度慢了一倍。

     爲此,在地址變換機構中增設一個具有並行查找能力的高速緩衝存儲器----快表,又稱相聯存儲器(TLB),用來存放當前訪問的若干頁表項,用來加速地址變換的過程(快表不在內存中)與此相對應的是,在內存中的慢表,具有快表的地址變換機構如圖所示

å¨è¿éæå¥å¾çæè¿°

 

 在具有快表的分頁機制中,地址的變換過程如下:

①CPU給出邏輯地址後,由硬件進行地址轉換,把頁號送入快表中,並將該頁號與快表中存儲的所有頁號進行比較

②若找到匹配的頁號,說明所要訪問的頁表項在快表中,則直接從中取出與該頁對應的頁框號,並與頁內偏移拼接形成物理地址,這樣,存取數據僅需訪問內存一次。

③若未找到,則需要訪問內存中的頁表,在讀出頁表項後,應同時將其存入快表中,以便日後可能再次訪問,但若快表已滿,則應考慮頁面替換策略來替換舊的頁表項。

注意:有些處理機設計爲快表和慢表同時進行查找,如果快表查找到了,則需要停止慢表的查找。

一般快表的命中率高達90%以上,這樣分頁帶來的速度損失率就可以降到10%以下,快表的有效性是基於著名的局部性原理。( CPU訪問存儲器時,無論是存取指令還是存取數據,所訪問的存儲單元都趨於聚集在一個較小的連續區域中。)

å¨è¿éæå¥å¾çæè¿°

 å¨è¿éæå¥å¾çæè¿°

(4)兩級頁表

    通過引入分頁管理存放方式,進程在執行過程中不需要將所有頁面都調入內存,而只需將保存映射的表調入內存。但是,我們依舊需要考慮頁面的大小。以32位邏輯地址空間,頁面大小爲4KB,頁表項大小爲4B舉例,若要實現進程對全部邏輯地址空間的映射,則需要2^32B/4KB=2^20個頁表項,即約10萬個頁表項,而一個頁表項大小爲4B,則頁表項所佔內存大小爲4MB(需要的頁面爲4MB/4KB=2^10=1024個頁面),也就是說一個進程僅頁表項就佔這麼大的空間,可以想象在電腦裏有多少進程,這樣會極大的佔用內存空間,拿一個40MB的進程來說,頁表項爲40KB(40MB/4KB×4B),即需要10個頁框來保存整個頁表(40KB/4KB=10),整個進程約爲10萬個頁面(40MB/4KB=10×2^10),但是實際上執行時只需要轉入幾十個頁面即可運行。若是要求10個頁面大小的頁表必須全部進入內存,則相對來說比較浪費;從另一方面來說,這10頁的頁表項也不需要全部同時保存在內存中,因爲在大多數情況下,映射所需要的頁表項都在頁表的同一個頁面(局部性原理)。

   爲了壓縮頁表,我們引入了二級頁表映射的思想,就可得到二級分頁,即使用層次結構的頁表:將頁表的10個頁面也進行地址映射,建立上一級頁表,用於存儲頁表的映射關係。這裏對頁表的10個頁面進行映射只需要10個頁表項,所以上一級頁面只需要1頁就可以裝下(1頁可以裝4KB/4B=1K=1024個頁表項)。在進程執行時,只需要將這一頁調入內存即可。以32位邏輯地址空間,頁面大小爲4KB,頁表項大小爲4B,以字節爲編址單位舉例,我們構造一個合適的頁表結構。頁面大小爲4KB,頁內偏移地址爲log以2爲底4K的對數爲12位,頁號部分爲20位,若不採用分級頁表,則光頁表就要佔用2^20×4B/4KB=1024頁,這遠遠超過了許多進程自身的需要,若是把這些頁表都放入內存連續的空間中,則查詢對應頁的物理頁號可以通過首頁地址+頁號×頁表項的大小來得到,這種查詢方法雖然方便,但是對於內存來說是極大佔用內存的,由於局部性原理,大多數頁面並不常用,所以這種方法不可行。若是不把這些表放在連續的空間裏,則需要一張索引表來存放這些表的邏輯地址 ,這就可以解決頁表佔用內存過大的問題。這就是構造了一個頁表的頁表,也叫做二級頁表。爲了查詢方便,頂級頁表最多隻能由1個頁面。因此頂級頁表可以容納4KB/4B=1K個頁表項,它佔用的地址位數爲log以2爲底1K的對數等於10位,又因爲頁內偏移佔12位,所以剩下10位正好使得耳機頁表在一頁之內(一頁爲12位)

一級頁表 二級頁表 頁內偏移

二級頁表實際上是在原有頁表結構上再加一頁。

建立多級頁表的目的在於建立索引,這樣既可以不用浪費內存空間去存儲無用(不常用)的頁表項,也可以不用盲目地順序式查找頁表項。

2. 基本分段式存儲管理方式

   分頁管理方式是從計算機的角度考慮設計的,目的是提高內存的利用率,提升計算機的性能;分頁通過硬件機制實現,對用戶完全透明。分段管理方式則是從用戶和程序員的角度出發,爲了方便編程、信息保護和共享、動態增長以及動態鏈接等方面來設計的。 (地址空間是二維的)

(1)分段 段式管理方式按照用戶進程中的自然段劃分邏輯空間。例如,用戶進程由主程序,子程序,棧和一段數據組成,就可以把這個用戶進程劃分爲4段,每段從0開始,並分配一段連續的地址空間(段內要求連續,段間不要求連續,因此整個作業的地址空間是二維的),其邏輯地址由段號s和段內地址偏移w組成。

31   ...   16 15   ...   0
段號s 段內偏移量w

 

上圖中,段號爲16位,段內偏移量爲16位,因此一個作業最多有2^16=65536段,最大段長爲2^16=64KB 

在頁式系統中,頁號和頁內地址偏移量對用戶是透明的,但是在段式系統中,段號和段內地址偏移必須由用戶顯式地提出(因爲地址空間不連續),在高級程序設計語言中,該工作由編譯程序來完成。

(2)段表       每個進程空間有一張邏輯空間與內存空間映射的段表,其中每個段表項對應進程的一段(每個段都在段表中有一個段表項,類似於分頁管理),段表項記錄該段的始址和長度。段表的內容如下圖所示:

段號 段長 本段在內存中的始址

 

配置段表後,執行中的進程可以查找段表,每段都可以在段表中找到一個對應的段表項,用來尋找每段在內存中的對應分區。可見,段表用於實現從邏輯段到物理內存區的的映射。

å©ç¨æ®µè¡¨å®ç°å°åæ å°

(3)地址變換機構  分段系統的地址變換過程如下圖所示。爲了實現進程從段表地址到物理地址的轉換,在系統中設置了段表寄存器,用來存放段表項的段表始址F與段表長度M。從邏輯地址A到物理地址E的變換過程如下:

①從段表中取出前幾位的段號S和後幾位的段內偏移量S。

②拿段號S與段長進行比較,若是S≥M,則發生越界中斷;否則,順利執行,取出段表項的內容。

③段表中段號S對應的段表項地址=段表項始址+段號×段表項長度,取出該段表項的前幾位得到段長C,若是W≥C,則產生越界中斷。否則,取出該地址對應的段表項的內容b,E=b+W,用得到的物理地址E去訪問內存。

分頁系統一樣,當段表放在內存中時,每要訪問一個數據,都須訪問兩次內存,從而極大地降低了計算機的速率。解決的方法也和分頁系統類似,再增設一個聯想存儲器,用於保存最近常用的段表項。由於一般情況是段比頁大,因而段表項的數目比頁表項的數目少,其所需的聯想存儲器也相對較小,便可以顯著地減少存取數據的時間,比起沒有地址變換的常規存儲器的存取速度來僅慢約10%~15%。(此段來源於百度)

(4)段的共享與保護  在分段式系統中,段的共享是通過兩個作業的段表中的相應的段表項指向被共享的段表項所對應的同一個物理副本來實現的。當一個作業正在從共享段中讀取數據時,另一個作業則不能修改此數據。不能修改的代碼稱爲純代碼或可重入代碼(它不屬於臨街資源)。這樣的代碼和不可能修改的數據可以共享,而可以修改的代碼或數據不可以被共享。

分段管理的保護方法主要有兩種:一種是存取控制保護,一種是地址越界保護。而地址越界保護需要比較兩次,第一次是段號和段長的比較,另一種是段內地址偏移和段長的比較;分頁管理中地址越界保護則只需判斷頁號是否越界,頁內地址偏移是不會越界的(因爲只有一個頁表只有一個頁表項)

段式管理不能通過給出一個整數便確定對應的物理地址,因爲每段的長度是不固定的,無法通過整數除法得到段號,無法通過取餘得到段內地址偏移,所以段號和段內地址偏移一定要顯式地給出,因此分段管理的地址空間是二維的。

3. 段頁式管理方式

頁式存儲方式能有效地提高內存利用率,而段式存儲管理方式能反映程序地邏輯結構和便於段的共享,因此,可將這兩種存儲管理方式結合起來,從而形成了段頁式存儲管理方式。

在段頁式存儲管理方式中,先將作業的地址空間分爲若干邏輯段,每段都有自己的段號,然後將每段都按頁式存儲管理方式那樣,分成若干大小相同且固定的頁(即存儲塊),對內存的分配仍舊以存儲塊爲單位。

在段頁式系統中,作業的邏輯地址分爲三部分:段號,頁號,頁內偏移量,段頁式地址的邏輯結構如下圖所示:

段號S 頁號P 頁內偏移量W

 爲了實現地址變換,系統爲每個進程都配備了一張段表,段表中包含各個段表項,段表項應該至少包含,段號,頁表長度和頁表始址,而每個頁表項應該包括頁號和塊號,此外,系統中還應該有一個段表寄存器,指出作業的段表始址和段表長度。

注意:一個進程只有一張段表,但可以有多個頁表。

在進行地址變換時,首先通過段表查找到頁表始址,再通過頁表查找到頁框號,最後形成物理地址。

進行地址變換時,首先利用段號S,將它與段表長TL進行比較。若S<TL,表示未越界,於是利用段表始址和段號來求出該段所對應的段表項在段表中的位置,從中得到該段的頁表始址,並利用邏輯地址中的段內頁號P來獲得對應頁的頁表項位置,從中讀出該頁所在的物理塊號b,再利用塊號b和頁內地址來構成物理地址。(來源於百度)

 在讀取數據段時,需要至少訪問內存三次,因此可以同樣配置一個快表,來存取段表和頁表,僅需訪問內存一次

因此,該方式的邏輯地址空間也是二維的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章