570 likes | 881 Views
作業系統. 第八章 記憶體管理. 教學目標. 記憶體的基本運作模式 位址空間的概念 連續記憶體的配置 斷裂的問題 分頁 分段的概念 兼採分段與分頁的實例. 序論. 一開始因為記憶體的零件很貴,所以得省著用。 拜 IC 設計技術的進步所賜,記憶體的容量不斷增大,價格也逐漸便宜下來。 CPU 的能力增加了,所以也增加了系統可以執行的程式數目。 記憶體單元由許多大小不一的使用者行程所共用。 因為「共用」,所以需要「管理」。. 記憶體的基本運作模式. 行程載入記憶體之後,如何知道程式碼所用到的所有記憶體存取工作要對應記憶體的哪個位址?
E N D
作業系統 第八章 記憶體管理
教學目標 • 記憶體的基本運作模式 • 位址空間的概念 • 連續記憶體的配置 • 斷裂的問題 • 分頁 • 分段的概念 • 兼採分段與分頁的實例
序論 • 一開始因為記憶體的零件很貴,所以得省著用。 • 拜IC設計技術的進步所賜,記憶體的容量不斷增大,價格也逐漸便宜下來。 • CPU的能力增加了,所以也增加了系統可以執行的程式數目。 • 記憶體單元由許多大小不一的使用者行程所共用。 • 因為「共用」,所以需要「管理」。
記憶體的基本運作模式 • 行程載入記憶體之後,如何知道程式碼所用到的所有記憶體存取工作要對應記憶體的哪個位址? • 利用位址連結 (address binding)達成。 • 何時進行位址連結? • 編譯時 (compile time) • 載入時 (load time) • 執行時 (run time)
動態載入 (Dynamic Loading) (1) • 是指使用者程式要用到的某些常式(routine)一開始並不會載入記憶體中,只有當使用者程式呼叫的時候才會載入。 • 程式先以可重定位的程式碼型態存在磁碟中。
動態載入 (Dynamic Loading) (2) • 當使用者程式載入記憶體並執行到動態載入程式時,呼叫可重定位的鏈結載入程式(relocatable linking loader)來把要用的程式載入記憶體 並執行。 • 好處 : • 不會使用到的程式碼永遠不會被載入記憶體。
動態鏈結(Dynamic Linking) • 和靜態鏈結(static linking)區隔。 • 做法: • 當使用者程式要用到系統程式庫時,在程式碼參考(reference)系統程式庫的地方做個記號(stub)。 • 這段記號用來指示如何去找尋要用的程式庫,如果已載入記憶體的話該去哪個位址參考,如果還沒載入的話該去磁碟的哪裡載入。 • 優點: • 有用到的系統程式庫在記憶體裡只會存在一份,不會重複。 • 鏈結的工作只需進行一次。 • 使用動態鏈結將可使程式庫更新變得更簡單。
重疊(Overlays) • 有時在執行的時候,並不需要把整個程式載入記憶體中。 • 在執行的過程中有時候只需要程式的某些部分,而有時候只需要程式的另外一些部分。 • 執行時只把必需的程式碼載入系統,不需要的部分先不要載入,即可省下很多記憶體空間。 • 對象 • 記憶體小而要執行大程式的計算機系統。
採用重疊技巧的實例 -兩階段組合程式(two-pass assembler) • 兩階段組合程式: • 採用兩階段步驟把程式的組合碼(assembly code)轉為機器碼(machine code)的組合程式。 • 要放入記憶體的資料: • 除了本身和其他需要的一般常式之外,還會產生第1次處理的程式碼、第2次處理的程式碼、符號表(symbol table)等。
範例: 兩階段組合程式各部分所需要的記憶體大小
置換出 (Swap Out) 行程A 行程A 行程B 置換入 (Swap In) 行程B 實體記憶體 磁碟空間 置換(Swapping)
位址空間的概念 • 在程式碼產生的時候,可以看出牽涉到記憶體存取的部分,會出現標示為記憶體位址的資料。 • 這類由CPU所產生的位址,稱為邏輯位址(logical address)。 • 要執行時,程式的這些部分在經過一些必要的處理之後,會變成對記憶體有意義的位址值。 • 這樣的位址,稱為實體位址(physical address)。 • 邏輯位址空間 • 所有邏輯位址所形成的集合。 • 實體位址空間 • 而所有實體位址所形成的集合。
連續記憶體的配置 • 可供使用者行程使用的記憶體空間可以被視為一大塊連續的區域。 • 如果僅有單一個行程來使用,問題會較單純。 • 考慮同時有很多個行程在使用記憶體的情況下,又是另一個問題。
單一分割配置(Single-Partition Allocation) • 系統內同一個時間只有一個行程在使用記憶體,則可將整個記憶體空間視為單一的區塊。在這種狀況下進行的記憶體配置,稱為單一分割配置。 • 可以搭配重定位暫存器(relocation register)、邊界暫存器(boundary register)以及MMU來完成。 • 適用於把常駐作業系統置於低位址記憶體空間而使用者行程使用高位址空間的系統。 • 好處: • 提供記憶體保護。 • 可以動態地改變常駐作業系統所占的記憶體空間大小。
利用邊界暫存器和重定位暫存器來進行記憶體配置利用邊界暫存器和重定位暫存器來進行記憶體配置
多重分割配置(Multiple-Partition Allocation) • 把整個記憶體空間劃分為一些固定大小的分割,每個分割只載入一個行程。 • 當有空著的分割時,即從在佇列中等待的行程中選出一個來載入記憶體。 • 等到行程執行結束之後,其佔用的記憶體分割則被釋放出來。 • 此為固定分割方法的一般化。
配置記憶體的策略 • 最先合適(First-Fit): • 遇到第一個夠大的「坑洞」就把行程載入。 • 最佳合適(Best-Fit): • 把每一個夠大的「坑洞」都拿來看看,然後選其中最小的一個來載入行程。 • 最差合適(Worst-Fit): • 也是把每個夠大的「坑洞」都拿來看看,然後選最大的可用空間來載入行程。
效能比較 • 最先合適和最佳合適在時間和記憶體空間的使用率上優於最差合適。 • 在記憶體空間使用率上,最先合適與最佳合適很接近。 • 最先合適的執行時間通常會比較短。
斷裂(Fragmentation) • 要讓行程載入記憶體,得先配置一塊「足夠的空間」 。 • 所謂「足夠的空間」,除了記憶體的大小要滿足行程所需之外,還得要是「連續」的空間才行。 • 因為不連續的關係,而使得行程不能載入的狀況,稱之為外部斷裂(External Fragmentation)。
外部斷裂(External Fragmentation) • 有外部斷裂發生時,會「浪費」記憶體。 • 浪費的記憶體多寡,與選擇配置的演算法有關。 • 所造成的記憶體浪費程度,主要是和記憶體空間總量以及行程的平均大小有關。 • 百分之五十法則(50-percent rule) • 在最佳的狀況下,當配置了n單位的記憶體空間時,還是會因外部斷裂而多浪費了n/2單位的空間。
作業系統 100K P4 200K P1 150K 可用空間=100+150+100 =350 >200(所需空間) P2 100K P3 外部斷裂之範例
解決外部斷裂的方法 • 內部斷裂(Internal Fragmentation) • 當有夠大的「坑洞」可以使用時,配置記憶體時就乾脆把整個可用空間都要走。 • 所謂的內部斷裂,是指配置出來的記憶體裡有一小段用不到的空間。 • 好處是減少了記憶體「小碎塊」發生的機會,可用的記憶體空間也比較容易連續地聚集在一起。 • 聚集(compaction) • 是把記憶體內零星的可用空間收集起來,並進一步「聚集」成大一點的「坑洞」。
作業系統 作業系統 100K 聚集 P1 350K 150K P1 P2 P4 P2 100K P3 P3 (a) (b) 聚集的範例
分頁(Paging) • 為了解決外部斷裂的問題。 • 允許行程內的邏輯位址空間可以不連續。 • 只要實體記憶體有足夠的可用空間,整個行程就一定可以載入記憶體去執行。
一般分頁實作的設計 • 把邏輯上行程所需的記憶體以及實體記憶體空間切成許多大小相同的小區塊。 • 實體記憶體上的小區塊稱為欄位(frame) 。 • 邏輯記憶體裡的則稱為分頁(page)。 • 在行程還沒載入之前,所有的分頁都儲存在備份儲存體上。
分頁表的實作(1) • 儲存分頁表的方式,一般的作業系統都是為每一個行程準備一個分頁表。 • 如何將行程和分頁表做個關聯? • 在行程控制區塊(PCB,Process Control Block)裡儲存一個指向記憶體中分頁表位置的指標。 • 基於效能上的考量,分頁表通常以硬體來實作, 最先想到的是用暫存器來儲存。 • 如果說系統允許分頁表很大,便改把分頁表存到主要記憶體中,並用分頁表基底暫存器來儲存分頁表的基底位址 。
分頁表的實作 (2) • 以PTBR來處理分頁表的好處是節省內容切換(context-switch)的時間,但是存取資料時需要多耗費一倍的時間。 • 解決方法:改用相關暫存器(associative register)或翻譯側看暫存區(translation look-aside buffer, TLB)。 • TLB是由特別的高速記憶體所組成,裡面分為兩個區域:key區和value區。
效能的評估 • 用兩種指標來評估 • TLB的命中率(hit ratio): • 要存取的分頁資料可以在TLB中找到的機率。 • 有效記憶體存取時間(effective memory access time) : [有效記憶體存取時間] = [命中率] × [在TLB可以找到分頁的記憶體存取總時間] + (1-[命中率]) × [在TLB找不到分頁的記憶體存取總時間]
分頁的保護機制 • 往存取權利與存取範圍兩個方向進行。 • 存取權利的保護,是在分頁表上的分頁資料裡使用保護位元(protection bit)來達成。 • 存取範圍的保護,是在分頁表裡的每一項資料上另加個有效-無效位元(valid-invalid bit)。 • 當此位元設為1時,代表此分頁表資料是有效的。換句話說,此位元設為0時,則代表這項分頁表資料無效。 • 所謂分頁表資料無效,是指此分頁不存在於執行中行程的邏輯位址空間內。
多層分頁(Multilevel Paging) • 分頁表所占的記憶體空間還是得想辦法縮小,以節省空間。 • 記憶體也沒有足夠的連續空間容納整個分頁表。 • => 把原本在分頁表上的資料區分為很多群 ,形成有層次的分頁表。
反轉分頁表(Inverted Page Table) • 同樣是面對分頁表太大的問題,與其每個行程都配置了一個分頁表,不如作業系統畫出一個特別的區域,專門儲存所有行程的分頁資料。 • 儲存分頁資料的地方,稱為反轉分頁表(Inverted Page Table)。 • 每一項反轉分頁表的資料會紀錄三項資訊,分別是行程識別碼(Process Identifier)、此分頁在實體記憶體上對應的欄位數和偏移量。 • 實體記憶體上的每個欄位在反轉分頁表中最多只會出現1次。
分頁共用(Shared Pages) • 使用分頁機制可以共用相同的程式碼。 • 做法: 把可以共用的程式碼集中在幾個分頁上,然後標示這些分頁。 • 共用分頁上的程式碼,都是屬於可重入的(reentrant)程式碼。 • 共用分頁是唯讀的,不應該被修改。 • 採用反轉分頁表的實作對分頁共用會有困難。
分段(Segmentation) 的概念 • 從使用者的觀點來看,記憶體的模樣是由許多不同大小的分段(segment)所組成,這些分段之間並沒有先後順序的關係。 • 由這種觀點出發,衍生出來管理記憶體的方法便稱為分段法(Segmentation)。 • 在分段法的機制中,每個分段都有一個名稱,也紀錄了其長度。 • 邏輯位址即由<分段號碼,偏移量>這樣的組合所表示。
分段表(Segment Table)的實作 • 和分頁表類似,可以參考分頁表的做法。 • 但不適合用暫存器來儲存分段表項目,應該把分段表存於記憶體裡。 • 用分段表基底暫存器(Segment Table Base Register,STBR)儲存分段表的起始位置。 • 用分段表長度暫存器(Segment Table Length Register,STLR)記錄分段表的長度。 • 採用相關記憶體暫存器(associative memory register)來儲存近來常用到的分段表資料,減輕因多一次記憶體參考所帶來的影響。
分段帶來的效益:保護與共用 • 分段法可以帶來兩項好處,分別是可以對資料或程式碼進行保護和共用。 • 保護措施 : • 在分段表上為每個項目準備保護位元(protection bit)。 • 當保護位元設為1時,表示該項資料代表的分段是被保護著而不能修改內容而且要照其屬性使用。 • 可共用的原因: • 資料與程式碼都會被劃分為一個一個獨立的分段,而且可以被定義為唯讀與唯執行。 • 每個行程會有一個對應的分段表,還允許同一個分段出現在不同行程的分段表項目中。
斷裂的問題 • 採用分段法也會遭遇到斷裂(fragmentation)的問題。 • 分段法是屬於動態重定位(dynamic relocation)的做法,因此可以選擇用聚集的方式 來解決斷裂的問題。