OS之内存管理 ---基本的内存管理策略(二)
分段
基本方法
分段就是基于用戶視圖的內存管理方案。邏輯地址空間是由一組段構成的,每個段都有名稱和長度。地址指定了段名稱和段內偏移。因此用戶通過兩個量來指定地址:段名稱和段偏移。
為了簡單,進行對段的編號,是通過段號而不是段名稱來引用的,所以邏輯地址由有序對組成:<段號,偏移>。
分段硬件
用戶是通過二位地址來引用程序內的對象的,但是實際物理內存仍然是一維的字節序列。所以我們需要定義一個實現方式,用來映射用戶定義的二維地址到一維的物理地址。這個地址是通過段表來實現的。段表的每個條目都有段基地址和段界限。段基地址包含該段在內存中的開始物理地址,段界限指定該段的長度。
段表的使用如上圖所示,每個邏輯地址由兩部分組成:段號s和段偏移d。段號用作段表的索引,邏輯地址的偏移d應位于0和段界限之間。如果不是這樣,那么會陷入操作系統中(邏輯地址試圖訪問段的外面);如果d合法,那么就與基地址相加而得到所需字節的物理內存地址。因此,段表實際上是基址寄存器值和界限寄存器值的對的數組。
分頁
分段允許進程德爾物理地址空間是非連續的。分頁是提供這種優勢的另一種內存管理方案,使用分頁可以避免外部碎片和緊縮。
基本方法
實現分頁的基本方法涉及將物理內存分為固定大小的塊,稱為幀或頁幀;而將邏輯內存也分為同樣大小的塊,稱為頁或頁面。當執行一個進程時,它的頁從文件系統或備份存儲等源處,加載到內存的可用幀。備份存儲劃分為固定大小的塊,它與單個內存幀或與多個內存幀(簇)的大小一樣。
分頁的硬件如下圖所示,由CPU生成的每個地址分為兩部分:頁碼§和頁偏移(d)。頁碼作為頁表的索引。頁表包含每頁所在的物理內存的基地址。這個基地址和頁偏移的組合就是物理內存的內存地址,可發送到物理單元。
頁大小是由硬件決定的。頁的大小為2的冪,如果邏輯地址空間為2m2^m2m,且頁大小為2n2^n2n字節,那么邏輯地址的高m-n位表示頁碼,而低n位表示頁偏移。
其中p為頁表的索引,d為頁的偏移。
采用分頁方案不會產生外部碎片:每個空閑幀都可以分配給需要他的進程,但是,分頁有內部碎片。分頁是以幀為單位進行的,如果進程所要求的內存并不是頁的整數倍,那么最后一個幀就用不完。如果進程大小與頁大小無關,那么每個進程的內部碎片的均值為半頁。
硬件支持
頁表的硬件實現有多種方法,最簡單的一種方法就是:將頁表作為一組專用的寄存器來實現。這些寄存器應用告訴邏輯電路來構造,以高效的進行分頁地址的轉換。CPU分派器在加載其他寄存器的時候,也需要加載這些寄存器。注意,這種方法適用于頁表比較小的情況下。
大多數的現代計算機都允許頁表非常大,對于這種情況,需要將頁表放在內存中,并將頁表基址寄存器指向頁表。改變頁表只需要改變這一寄存器就行了。注意,如果采用這種方法,訪問一個字節需要兩次訪問內存(一次用于頁表條目,一次用于字節)。
標準方法是:采用轉換表緩沖區(TLB),TLB是關聯的高速內存,TLB條目是由兩部分組成:鍵(標簽)和值。當關聯內存根據給定值查找時,它會同時與所有的鍵進行比較。如果找到條目,就得到相應值的字段。
TLB和頁表一起使用的方法是:TLB只包含少數的頁表條目。當CPU產生一個邏輯地址后,它的頁碼就發送到TLB。如果找到這個頁碼,它的幀碼就立即可用,可用基于訪問內存。如果頁碼不在TLB中,也就是TLB未命中。那么就需要訪問頁表。有的TLB在每個TLB條目中還保存地址空間標識符(ASID),ASID唯一標識每個進程,并為進程提供地址空間的保護。
保護
分頁情況下的內存保護是通過與每個幀關聯的保護位來實現的。用一個位可以定義一個頁是可讀可寫的還是只可讀。每次內存引用都要通過頁表,來查找正確的幀碼。在計算物理地址的同時,可以通過檢查保護位來驗證與沒有對只讀頁進行操作。
還有一個位通常與頁表中的每一條目相關聯:有效-無效位。當該位為有效時,該值表示相關的頁在進程的邏輯地址空間內,因此是合法的頁。當該位是無效的時候,該值表示先關的頁不在進程的邏輯地址空間內。通過使用有效-無效位,非法地址會被捕捉到。
還有一個問題,一個進程很少會使用的它的所有地址空間,如果為地址范圍內的所有頁都在頁表中建立一個條目,這將是非常浪費的。有的系統會提供硬件來解決這個問題,如**頁表長度寄存器(PTLR)**來表示頁表的大小,該寄存器的值可用于檢查每個邏輯地址以驗證其是否位于進程的有效范圍內。
共享頁
分頁的優點之一就是可以共享公共代碼。
注意:代碼必須是可重入代碼或純代碼才可以共享。可重入代碼是不能自我修改的代碼,他在執行期間不會改變
頁表結構
分層分頁
現代操作系統支持大邏輯地址空間,在這種情況下頁表本身可以非常的大。比如一個位邏輯地址空間的計算機操作系統。如果系統的頁大小為4KB(2122^{12}212),那么頁表可以多達100萬的條目,假設每個條目有4字節,那么每個進程需要4MB物理地址空間來存儲頁表本身。
常用的解決方法就是分層分頁。比如兩層分頁算法,就是將頁表在分頁。
其中p1p_1p1?是用來訪問外部頁表的索引,p2p_2p2?是內部頁表的頁偏移,這種方案一般稱為向前映射頁表。
對于64位的架構,分層分頁是不適用的,因為每一層的頁表分完之后還是太大了。
哈希頁表
處理大于32位地址空間的常用方法就是使用哈希頁表。采用虛擬頁碼作為哈希值。哈希頁表的每一個條目都包括一個鏈表,該鏈表的元素哈希到同一位置(該鏈表用來解決碰撞)。每個元素由三個字段組成:
該算法的工作:虛擬地址的虛擬頁碼哈希到哈希表。用虛擬頁碼與鏈表內的第一個元素的第一個字段相匹配。如果匹配,那么相應的幀碼就用來形成物理地址;如果不匹配,那么與鏈表內的后續節點的第一個字段進行比較,以查找匹配的頁碼。
基于哈希頁表的一個變體采用聚簇頁表,哈希表中的每個條目引用多個頁而不是單個頁,因此單個頁表條目可以映射到多個物理幀。聚簇頁表對于稀疏地址空間特別有用,這里的引用是不連續的并且散步在整個地址空間中。
倒置頁表
通常情況下每個進程都有一個頁表,該進程使用的每個頁都是該頁表的一項。但是這種方法的缺點就是會造成每個頁表可能包含數以百萬記的條目,占用大量的內存。
所以有了倒置頁表。對于每個真正的內存頁或幀,倒置頁表才有一個條目。每個條目包含保存在真正內存位置上的頁的虛擬地址以及擁有該頁進程的信息。所以在一個系統中只有一個頁表,并且每物理內存的頁只有一條相應的條目。
由于一倒置頁表通常包含多個不同的映射物理內存的地址空間,通常要求它的每個條目保存一個地址空間標識符,用來確保具體進程的每個邏輯頁可映射道德相應的物理幀。
參考:《操作系統概念》(第九版)
轉載于:https://www.cnblogs.com/lishanlei/p/10707669.html
總結
以上是生活随笔為你收集整理的OS之内存管理 ---基本的内存管理策略(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消息队列之推还是拉,RocketMQ 和
- 下一篇: 五年了,你还在用junit4吗?