存儲管理

無存儲抽象
使用簡單的物理內存:地址從0開始的有限地址集合,每個地址是一個8位的存儲單元。
程序執行時,從磁盤放入內存中,進程運行完程序後,將新的程序從自盤裝入內存,覆蓋上一個程序
要想運行多道程序,需要將當前內存中的所有內容保存到磁盤中,將新程序裝入內存再運行即可。
把物理地址暴露給進程,運行多道程序不可避免會造成程序跳轉到不正確的地址而崩潰,而且有容易存放操作系統的空間。

地址空間
進程可用於尋址內存的一套地址集合。每個進程擁有自己的地址空間,進程間的地址空間互不干擾。

基址寄存器和界限寄存器
這兩個寄存器用來將進程的地址映射到實際的物理地址中,並保證每個進程的地址空間相互獨立。基址寄存器存放着程序的起始物理地址,而界限寄存器存放着程序的長度。
進程訪問內存時,CPU會用虛擬地址加上基址寄存器的值,然後再從地址總線上尋址物理內存,同時檢查程序的地址是否超過了界限寄存器的值。
使用基址寄存器和界限寄存器重定位的缺點是,每次訪問內存需要進行加法計算和比較計算,加法計算在沒有特殊電路的情況下會很慢。
基址寄存器和界限寄存器

上述方案在進程較少的情況下可行,但現代操作系統的進程很輕易就超過內存容量。
處理內存超載的兩種方法,一種是交換技術,另一種是虛擬技術。

交換技術
A和B進程
把進程完整地裝入內存,在進程空閒時,存入磁盤,騰出空間給新進程。這個技術的問題在於,無法確定當進程被裝入內存時,該分配多大的空間。假設程序的數據段是可增長的,比如它動態的從堆中分配內存,那麼進程空間試圖增長,如果內存不能增長,而磁盤的交換區也滿了,則進程只有掛起。

空閒內存管理
動態分配內存時,需要記錄內存的使用情況
1.使用位圖的存儲管理
將內存分成小到結構字大到幾千字節的分配單元。每個分配單元對應位圖中的一個位,0表示空閒,1表示被佔用。內存的大小和分配單元的大小決定了位圖的大小。當一個進程需要k個分配單元時,MMU從內存中尋找k個連續0的串。
2.使用鏈表的存儲管理
維護一個記錄已分配內存段和空閒內存段的鏈表。一個結點的數據段記錄進程或空閒區的起始地址和長度。段鏈表按照地址排序,當一個進程終止時,需要更新鏈表,將相鄰的空閒結點合併成一個空閒結點。

尋找空閒區的算法

首次適配算法:沿地址順序搜索,直到找到一塊足夠大的空間。
最佳適配算法:對整個空閒區大小排序,然後搜索整個鏈表,尋找能夠容納進程的最小空閒區。

爲進程和空閒區分別維護一個鏈表,這樣能集中檢查空閒區,提高速度。一個能提高性能的做法是,先按照大小對空閒區鏈表排序,然後使用最佳適配算法或首次適配算法,爲進程分配內存。

虛擬內存
解決程序日益增大的問題。
每個程序擁有自己的地址空間,這個虛擬地址空間(VMA)被分割成多個頁,每個頁地址連續。通過MMU管理虛擬地址空間到物理內存的頁映射,運行程序是指將程序引用到的頁裝載進內存

分頁
虛擬地址到物理地址過程
程序給出的虛擬地址首先發送到MMU上,通過查找映射表,然後將真實的物理內存地址發送到總線上。

頁表頁框映射
叉號表示頁面不在內存中。如果程序引用到的頁面沒有映射,則CPU陷入操作系統,這個陷阱稱爲缺頁中斷,操作系統找到一個很少使用的頁框,並把內容寫入磁盤中,把需要訪問的頁面讀到回收的葉框中,修改映射關係,重新回到中斷處執行。

MOV REG,32780

32780這個地址在VMA中32K_36K位置,但是該頁面沒有映射,引起一個操作系統陷阱。
假設操作系統決定放棄頁框1,則它將頁表中的虛擬頁面1改成叉號,然後將虛擬頁面8的叉號改爲1,將虛擬頁面8寫入頁框1。
MMU中具體實現如下

注意,輸入虛擬地址比輸出地址少1位,表明從64K映射到32K。低12位表示頁內偏移,直接從MMU輸入複製到輸出的低12位,高4位爲頁表的十進制格式的頁面號。

頁表
頁表的目的就是將虛擬頁面映射爲頁框。這個過程會裁剪輸入虛擬地址的高位中的某一個位或某些位。在一個分頁系統中創建新進程時,操作系統要確定程序和數據初始時多大,在內存中爲它們分配頁表。並在進程終止時,釋放頁表。
虛擬地址分爲兩部分,高位部分爲虛擬頁號,低位部分爲偏移量。例如,對於16位地址和4KB的頁面大小,高4位可以指定16個虛擬頁面中的一頁,而低12位確定了所選頁面中的字節偏移量(0~4095)。使用3或5或其他位數拆分虛擬地址也是可行的。不同劃分對應不同的頁面大小。

頁表項
頁表項是一個32位的地址(32位操作系統)。
頁表項
頁框號:映射的目的就是找到這個值。
在/不在位:1是有效,0則表示該表項對應的虛擬頁面不在內存中,訪問該頁面會引起一個缺頁中斷。
保護位:支出一個頁允許什麼類型的訪問。比如:0->讀/寫, 1->只讀。
修改位:它是用來記錄頁面使用情況的。在寫入一頁時有硬件自動設置修改位。如果一個頁面被修改過,那麼就是“髒”的,則必須把它寫回磁盤。反之就是“乾淨”的,簡單地丟棄就可以了。這一位有時也被稱爲髒位。

頁目錄、頁表、頁面三者關係
頁目錄和頁表都是存在線性地址(虛擬地址)裏面的。通過頁目錄中的頁表地址找到對應的頁表地址,再找到對應的頁面地址。對於32位操作系統而言,頁表項的大小爲4B指的應該是32bit的存儲空間。也就是說頁表項中數據爲4B(4*8=32),頁內偏移的大小(12位)決定了頁面的大小,也就是是4KB,如果在4GB的虛擬地址空間內,將頁面平鋪,則有4GB/2KB = 2^20個頁表項,因此採用多級分頁的策略,一個頁目錄一般有1024個頁表,一個頁表一般有1024個頁表項。如此一來就有1k*1K*4K = 4GB的空間被映射。

加速分頁過程
頁表放在內存中,當一條指令將一個寄存器值放入另一個寄存器時,有了分頁技術後,操作系統需要先訪問內存中的頁表,然後再從頁表中取對應的內存頁

轉換檢測區(TLB)
它將程序中少量常用的頁面放入一個硬件設備中,這個硬件設備通常在MMU中,如果MMU檢查到頁面地址在TLB中,則直接訪問頁面對應的物理內存。實際中,TLB的表項數量很少會超過64個。在分頁機制下,TLB的加入是爲了解決CPU多次訪問內存中的頁表而引起性能降低的問題。

軟件TLB管理
當在TLB表中找不到需要的頁面時,將TLB失效問題提交給操作系統。,操作系統更新TLB。
軟件處理TLB的速度快於硬件處理TLB的速度。

針對大內存的頁表
1、分級頁表

32位虛擬地址被分爲10位的PT1域,10位的PT2域以及12爲的Offset域。PT1域爲頂級頁表,有1024個項,每個頁表項表示4MB的內存空間,一共4GB。PT2域是次級頁表項也有1024個項,每一項表示4KB的頁大小,一共4MB。

2、倒排頁表
倒排頁表
實際內存中的一個頁框有一個表項,而不是每個虛擬頁面有一個表項。MMU不再根據頁號來索引物理頁框,而直接在搜索RAM的整個頁表來查找某個表項。

頁面置換算法

頁面置換的過程,當程序發生缺頁中斷時,系統查找時候有空閒頁框,如果沒有空閒頁框,需要將不常用的頁面換出內存,如果頁面在內存駐留期間被修改過,則重新寫入磁盤;否則,用用VMA中的新頁覆蓋裝入內存即可。

1、最優頁面置換算法
每個頁面被標記首次被訪問前所要執行的指令數,每次置換指令數數最大的頁面。
缺點是無法實現

2、最近未使用頁面置換算法(NRU)
現代操作系統中,每個頁面有兩個狀態位,R狀態位標記頁面是否被訪問過,W狀態位標記頁面是否被修改過。根據這兩個狀態位,將頁面分爲四類,分別是
第0類,沒有被訪問,沒有被修改
第1類,沒有被訪問,但是被修
第2類,被訪問過,沒有被修改
第3類,被訪問過,也被修改
NRU算法將按類別編號最小的非空類中挑選一個頁面被替換。

3、先進先出頁面置換算法
在一個時鐘滴答中,維護一個當前內存中所有頁面的鏈表,淘汰最早進入內存的頁面(表頭位置),放到鏈表的末尾。
缺點是可能會淘汰經常使用的頁面

4、第二次機會頁面置換算法
在FIFO算法的基礎上,淘汰最早進入內存並且沒有被訪問過的頁面。每次檢查R位是否爲0,如果爲0,直接置換掉;如果爲1,將其R爲清0,放入表尾,變成新裝入的頁面,繼續查找下一個頁面。

5、時鐘頁面置換算法
它爲了解決經常在鏈表中移動結點的問題,將鏈表變成環形鏈表,維護一個指針,指向未被訪問頁面,每次置換後,指針前移一個位置。

6、最近最少使用頁面置換算法(LRU)
在缺頁中斷髮生時,置換未使用時間最長的頁面
缺點是維護內存中所有頁面的鏈表需要特殊的硬件。

7、最不常用算法(NFU)

8、老化算法

NFU的改進,將每個頁面與一個軟件計數器關聯。紅線處出錯了,(d)的紅線處應改爲00010000

9、工作集頁面置換算法
請求調頁
頁面在需要時被調入,而不是預先裝入。

局部性訪問
進程運行的任何階段,它都只訪問較少的一部分頁面。這一部分頁也都比較集中。

工作集
一個進程當前正在使用的頁面的集合稱爲工作集。一個進程如果剛開始只裝入部分頁,會產生很多缺頁中斷,直到工作集整個裝入內存中時,完整裝入前的缺頁中斷會影響程序運行速度,爲了避免這個缺陷,分頁系統在進程運行前,會將整個工作集裝入內存。

顛簸
每執行幾條指令就發生缺頁中斷

預先調頁

在程序運行過程中,預先裝入推測出的工作集的頁面。
常見的推測工作集頁面的方法是,確定一個時間間隔T,將過去T時間間隔裏內存訪問到(即R=1)的頁面的集合。
生存時間=當前實際運行時間-上次使用時間

10、工作集時鐘頁面置換算法

缺點是實現起來開銷大

分頁系統的設計問題

局部分配策略和全局分配策略
局部分配和全局分配

b)是局部頁面置換,它只考慮分配給A的頁面,將生存時間最小的頁面替換掉
c)是全局頁面置換,在A、B、C三個進程集合中選擇最小生存時間的頁面替換掉。

缺頁中斷率
每秒的缺頁中斷數

負載控制
一旦所有進程的組合工作集超過了內存容量,就可能發生顛簸。解決方案是將進程從內存交換到磁盤中。決定交換哪個進程要考慮三個方面的內容
● 進程的類型,是屬於計算密集型還是I/O密集型
● 進程的大小
● 分頁率

頁面大小
頁面太大,造成內存碎片太多,浪費空間;頁面太小,頁表太大,花費在尋道和旋轉延遲的時間太長。

分離的指令空間和數據空間

爲指令和數據設置分離的地址空間,每個地址空間都是從0開始到最大值。

共享頁面
共享內存頁
這總情況下, 3、4、6頁面時進程P1、P2以及P3共享。程序頁總是隻讀的,因此共享程序也比共享數據頁簡單些。當共享頁面被回收,放入空閒頁面池時,所有共享了該頁面的所有地址空間的頁表都要同步更新。

共享數據的例子
在UNIX系統中,進行fork調用時,會創建父進程的副本,父進程和子進程要共享數據和程序,共享的方法是,將各自進程的頁表都指向一個頁面集合,而不進行復制頁面,只有在其中一個進程對數據頁面進程修改時才複製。這種做法稱爲寫時複製。

共享庫
當一個程序和共享庫鏈接時,鏈接器沒有加載被調用的函數,而是加載了一小段能夠在運行時綁定被調用函數的例程,在庫中定義但是沒有被調用的函數不會被加載,最終生成的可執行二進制文件也不包含這些未定義外部函數。
如果其他程序已經裝載了共享庫,就沒有必要再次裝載它了,並且共享庫被裝載時,不是一次性的讀入內存,而是根據需要,按頁裝入內存。

解決重定位的問題
如果庫被兩個進程共享,被不同的進程定位到不同地址上,就不能在裝載時重定位了。
解決辦法是不要產生使用絕對地址的指令。相反,只能產生使用相對地址的指令。
只使用相對偏移量的代碼稱爲位置無關代碼。

內存映射文件
進程發起一個系統調用,將一個文件映射到其虛擬地址空間的一部分。

有關實現虛擬內存系統的幾個問題
指令備份
在每條指令執行之前,將程序計數器的內容備份到寄存器中,以防止缺頁中斷後,系統無法重啓引起陷阱的指令。

鎖定內存的頁面
防止發生I/O通過DMA直接向內存頁中傳輸數據,但是該頁卻選中被置換的情況。
做法是鎖住正在I/O操作的內存中的頁面。

磁盤交換區

分段

分段管理
段是一個邏輯實體,程序員必須手動分段,並進行管理。段的長度不定,在運行一段時間後,內存會被分割成空閒區和段區相間,並且這些空閒區都不能使用了。

分段和分頁的區別
這裏寫圖片描述

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