操作系統八內存管理

CPU直接訪問的存儲器只有內存和處理器內的寄存器。

1.基本硬件

      CPU可以在一個cpu時鐘內執行一個或多個其內置寄存器的指令。而訪問內存需多個cpu時鐘。由於內存頻繁訪問,可以再cpu與內存之間增加高速緩存

爲確保進程有獨立的內存空間,可用基地址寄存器界限地址寄存器來確立一個合法地址以供其他進程訪問。基地址寄存器含有最小的合法物理內存地址,界限地址寄存器決定合法地址大小。如基地址和界限地址寄存器分別爲30050和120900,那麼合法地址爲30050到420950

2.邏輯地址空間與物理地址空間

      內存在字節的地址爲物理地址,cpu生成的地址爲邏輯地址。通常邏輯地址爲虛擬地址,從虛擬地址到物理地址的映射是由稱爲內存管理設備單元MMU的硬件來完成的。

      用戶進程只生成邏輯地址,且認爲其地址空間爲0到max。邏輯地址使用前需映射到內存的物理地址。MMU動態的將邏輯地址加上重定位寄存器的值後映射成物理地址。映射後的物理地址再送交內存單元。

3.連續分配內存

     內存通常分爲兩個區域,分別駐留操作系統和用戶進程。由於中斷向量通常位於低內存,操作系統也放在低內存。

3.1內存映射與保護

      通過重定位寄存器和界限地址寄存器可保護內存進程的獨立空間。當cpu調度器選擇一個進程執行時,作爲上下文切換的一部分,調度程序會用正確的值初始化重定位寄存器和界限地址寄存器,保證其他進程不受該進程運行所影響。

3.2內存分配

      最爲簡單的內存分配方法是MFT,即將內存分爲多個固定大小的分區,一個分區容納一個進程。MFT已不再使用,MVT是他的推廣,主用用於批處理系統。

      在可變分區方案裏,系統中有一個表用來記錄那些內存佔用還是未佔用。當有新進程需要內存時,爲該內存尋找足夠大的孔,從這個孔中爲該進程分配所需的內存,孔內未分配的內存可爲其他進程所用。從一組可用孔中選擇一個空閒孔最常用的方法有:首次適應、最佳適應、最差適應。首次適應最快最好

      首次適應和最佳適應都有外部碎片問題。並不連續的小內存稱爲碎片。 解決碎片問題方法之一是允許物理地址空間爲非連續:分頁與分段。

4.分頁

      傳統上,分頁由硬件處理。最近的設計是通過將硬件和系統相配合來實現分頁的。

      進程需要在內存中以便運行,不過進程可以暫時從內存中交換到備份存儲,當需要再次執行時再調回到內存中。如果進程地址綁定方式是在彙編時或加載時所定的,他只得移到原來內存空間。如果綁定是在運行時才確定,由於物理地址是在運行時才確定的,進程可移到不同地址空間。

4.1基本方法

      基本方法涉及將物理內存分爲固定大小的塊,稱爲幀(frame),而將邏輯內存也分爲同樣大小的塊,稱爲頁。當執行進程時,其頁從備份存儲(他也分固定大小的塊,大小與內存幀一樣)中調入到可用的內存幀中。

      由CPU生成的每個地址分爲兩個部分:頁號P和頁偏移d,頁號作爲頁表的索引。頁表包含每頁所在物理內存的基地址,這些基地址與頁偏移的組合就形成了物理地址,可送交給物理單元。

      頁與幀的大小一樣,是由硬件決定的。頁的大小通常爲2的冪,方便將邏輯地址轉爲頁號和頁偏移,根據計算機結構的不同,從512B到16M不等。

      當進程需要執行時,根據進程的大小計算頁數n,從而內存中也應該至少有n個幀用來分配給新進程。進程的第一頁裝入一個分配的幀,幀號放入進程的頁表中。

      如下圖所示

      頁大小爲4B,而邏輯內存爲32B(8頁),邏輯地址0的頁號爲0,頁號0對應幀5,因此邏輯地址映射爲物理地址5*4+0=20.邏輯地址3映射物理地址5*4+3=23.。邏輯地址13映射到物理地址9.

      採用分頁技術不會產生外部碎片,但可能產生內部碎片。內存的分配是以幀爲單位進行的,每個進程平均可有半個幀大小的內部碎片。

      分頁使用戶視角的內存與實際物理內存想分離。用戶無法訪問其他用戶程序佔用的內存。

4.2硬件支持

      頁表的硬件實現有多種方法。最簡單的是將頁表作爲一組專用寄存器來實現

4.3保護

      分頁環境下,內存保護是通過與每個幀相關聯的保護位來實現的。這新保護位通常位於頁表中。可用一個位來定義一個頁是可讀寫的還是隻讀的的,當對一個只讀的頁進行寫操作會使系統產生硬件陷阱。

4.4共享頁

      分頁的一個優點是可以看、共享公共代碼,這種考慮對分時環境很重要。

5.頁表結構

5.1層次頁表

      大多數計算機系統支持大邏輯地址空間(2的32到64的冪)。這種情況下,頁表本身非常大。我們並不可能在內存中連續的分配這個表。一個簡單方法是將頁表劃分爲更小部分。

      一種方法是使用兩級分頁算法,將頁表在分頁。以一個4kb頁大小的32位系統爲例。一個邏輯地址被分爲20位的頁碼和12位的頁偏移。因爲要對頁表進行再000分頁,所以該頁號可分爲10位的頁碼和10位 的頁偏移。這樣一個邏輯地址就表示如下形式:

      p1是用來訪問外部頁表的索引,p2是外部頁表的頁偏移,採用這種結構地址轉換方法如下圖所示。由於地址轉換由外向內,這種方案也稱爲向前映射頁表。

5.2哈希頁表

      處理超過32位地址空間的常用方法是使用哈希頁表(hashed page  table),並以虛擬頁碼作爲哈希值。哈希頁表的每一條目都包括一個鏈表的元素,這些元素哈希成同一位置。每個元素有三個域:虛擬頁碼 所映射的幀號 指向鏈表中下一個元素的指針。

      虛擬地址中的虛擬頁號轉換到哈希表中,用虛擬頁號與鏈表中的每一個元素的第一個域相比較。如果匹配,那麼相應的幀號就用來形成物理地址。如果不匹配,就對鏈表中的下一個節點進行比較,以尋找一個匹配的頁號:

      羣集頁表類似於哈希頁表,對於稀疏地址空間很有用,稀疏地址空間的地址引用不連續,且分散在整個地址空間

5.3反向頁表

      通常每個進程都有一個相關頁表。每個頁表有很多項。這可能消耗大量物理內存。爲解決這個問題,可以使用反向頁表。

6.分段

      採用分頁內存管理有一個不可避免的問題:用戶視角的內存和實際內存的分離。分段支持這種用戶視角:將內存看做一個線型數組,有的包含指令,有的包含數據。

      邏輯地址空間是由一組段組成的。每個段都有名字和長度。地址指定了段名稱和段內偏移。因此用戶通過兩個量來指定地址:段名稱和偏移。段是編號的,通過段號而非段名稱來引用。因此邏輯地址由有序對構成:

           <segment-number,offset>

通常,編譯程序時,編譯器會自動根據輸入程序來構造段。

      一個C編譯器可能創建如下段:代碼、 全局變量、堆、線程棧、C庫函數。

6.1.硬件

      段表的每個條目都有段基地址和段界限。段基地址包括段在內存中的開始物理地址,段界限指定段長度  

      一個邏輯地址段號S和偏移d組成。段號用作段表的索引,邏輯地址的偏移d應位於0和段界限之間。段偏移一段基地址之和就是物理內存地址。因此段表是一組基地址和界限寄存器對。

      如圖有5個段,編號0~4,例如段2爲400B開始於位置4300.對段2第53字節的引用映射成位置4300+53=4353

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