存儲器管理

@我是博客初哥,如若寫得不好,請多多提點。希望大家多多補充,互相學習。


        前言:這裏的存儲器一般是指內存,內存不僅爲CPU提供指令和數據,還有和I/O設備數據交換,可見存儲器的位置多麼關鍵,所以爲了改善CPU的資源利用率和對I/O的吞吐,如何管理存儲器變得很重要。存儲器管理是操作系統的功能之一,它包括存儲器的分配、保護和共享,後來引入了虛擬內存技術來解決物理內存小於進程地址空間的問題。


        進程申請的邏輯空間就叫做地址空間,物理內存的空間就叫做存儲空間。    


        在單道批處理系統和單用戶單任務系統中,內存的分配方式是單一連續區分配,也就是說一個作業(用戶程序)佔用其用戶進程區,所以,這一個作業就佔用了所有的系統資源,可想而知,資源的利用率很低。內存是有分區的,有用戶進程區、RAM區(操作系統駐留)、ROM區(BIOS,存放設備驅動)。如果用戶程序能夠跨越內存的區域操作,就會影響到系統,容易受到病毒***,就如DOS系統,它是沒有存儲保護功能的。單一連續區分配的存儲保護,只需要限定CPU訪問內存地址的範圍。如圖下,要限定m<addr<n。


wKioL1OmrijwtE3NAACEpRbP24k393.jpg


         對於多用戶多道程序系統,它把內存分爲若干個連續的區域,內存的分配方式是分區分配,分區分配又分爲固定式分區、可變式分區。分區分配實現了存儲器的共享功能,所謂共享,也就是說相同的程序或數據在內存上保留一份即刻,其代碼不會在執行過程中被修改。

        固定式分區就是預先分好不同大小的的區域,當進程申請空間的時候,它會去找最符合而且最小的區域;當遇到被佔用,就會等待。這種管理方法簡單,但是很可能會造成大區域的利用率少,小區域的隊列擁擠。因爲不可能每個進程的大小都跟預設好的區域一樣,所以這樣方法對資源的利用率比較低。它使用的地址就是主存的絕對地址,也就是物理的內存地址。

        可變式分區比起固定式分區靈活得多,它是根據進程要求申請的空間大小來劃分內存區域的,這樣分區方法由分區說明表和空表區鏈來記錄相關的信息。當系統回收一個釋放區的時候,它會和隔壁的空閒區合併成一個。當分配內存的時候,根據不同的需要用不同的分配算法:

(1)首次適應(first fit),從起始地址最小的空閒區開始掃描,直到找到一個足夠大的空閒區爲止;

(2)最佳適應(best fit),找到滿足進程需求的最小空閒區爲止;

(3)最壞適應(worst fit),找到滿足進程要求的最大空閒區爲止;這種方法的缺點是:當一個更大的進程申請的時候,就沒有空間給它申請了。

        以上的所有方法都是基於物理存儲空間>=進程地址空間,但是這個是不現實的。覆蓋技術和交換技術就是在邏輯上擴充了內存。

        程序是算法和數據結構組成,算法當中,有很多的語句,譬如循環語句、分支語句等等,在執行循環語句時,它會在當中一直反覆地執行某一部分的語句,這就是時間局部性;當執行分支語句的時候,如果分支1和分支2是互斥的,也就是說我選了分支1,分支2就不用被執行了,也就是我們可以先不把它放到內存上,等需要的時候再把分支1拿下,用分支2代替,這就是空間局部性。時間局部性和空間局部性就是程序的局部性原理

        覆蓋技術就是通過程序的空間局部性,打破了所有進程地址空間裝入存儲空間後才能執行。這個技術的關鍵是提供正確的覆蓋結構。

        交換技術就是當內存空間,進程用完分配的時間片或者等待I/O時,把內存中暫時不用的信息先轉移到硬盤上,在硬盤上的那部分文件就叫做交換文件。

        說了那麼多存儲器管理方法,是不是頭都暈了?挺住,下面還有。在我們不斷地申請和釋放內存空間的時候,會產生碎片。碎片分爲外部碎片和內部碎片,內部碎片就是你被分配了空間,但是有一部分你是沒有用到的;外部碎片就是空間很小,小得不能再利用來分配。其實我們可以通過拼接結束來把碎片拼接起來重新使用,但是這樣很耗內存的穩定性。爲了克服碎片問題,頁式管理就誕生啦。頁式管理把主存分割成相同大小(2的n次方)的若干塊,稱爲頁框,進程的地址空間也劃分成相同大小的若干塊,稱爲虛頁,虛頁包括10個字節的頁號和10個字節的頁內地址(邏輯地址)。頁表是邏輯地址和內存塊的橋樑,映射了他們兩個的關係,頁表是存放在內存上的,而且它在內存的始址上。當我們運行程序的時候,程序看到的是進程頁,看到自己哪個地址對應着哪條語句,看到的那個地址對應的頁號跟頁表長度比較,如果頁號>=頁表長度,就是它訪問的地址越界了(還記得內存用戶操作區嗎?這裏的話是超出了分配給程序的內存空間),就終止運行了。如果頁號<頁表,由(頁表始址+頁號X頁表項佔用的字節數)得到了該頁號在頁表的入口地址,然後就取得了對應的內存塊號。這就是頁式管理的地址變換。於是我們就可以訪問到對應的語句。再說說頁式管理的保護,其實就是linux文件的rwx標誌位的機制。

        但是每次訪問操作都產生了兩次對內存的訪問:一次是查詢頁表,一次是訪問對應的塊號。爲了克服這個缺點,我們引入了TLB(聯想存儲器translation lookaside buffer)和快表。其實就是把經常訪問的寫在快表,在查詢的時候快表和頁表一起查詢,當快表查到的時候,頁表查詢就中斷。

        說完頁式管理,還有一個就是段式管理。我們的程序是若干個程序段或數據段組成的,這樣更符合程序運行的邏輯。爲此,段式管理每個進程的地址空間都是按照程序自身的要求而劃分成若干段的。所以它的分配是隨機的,所以會產生碎片。其餘的話跟頁式管理差不多。

        最後一個啦!之前所說的頁式管理和段式管理,都是在進程的空間能夠完全映射在物理內存空間上,這是不現實的,所以又推出了比較成熟的頁式虛擬存儲管理、段式虛擬存儲管理。其實就是頁式管理+交換技術,段式管理+交換技術!夠簡單吧?不過我要補充的是,當內存滿了的時候,我們要考慮把內存上某一頁置換出來,而根據什麼來置換,就要根據頁面淘汰算法了。其實頁面淘汰算法纔是重點,有FIFO、NUR、OPT等等。有興趣的可以去看一下(我這裏有對應的程序)。

        最後要補充的是,頁面保護的問題,當一個頁被共享給多個進程讀的話,這個是完全沒問題的,但是如果多個進程在寫的話,就會有問題了:1.如過某個進程在寫的時候,我把頁置換掉了,那原本的資料是不是完蛋了?2.你改別人的資料別人知道嗎?你家人知道嗎?你老闆知道嗎?所以,這裏有一個保護機制就做寫時複製技術,就是你要寫的時候,就複製一分給你自己用,你在上面任意寫都可以。別人的那份還是沒有變。


        總結,單用戶單任務系統中,一個作業佔用全部用戶操作區,資源利用率低,其存儲保護是通過限制CPU訪問內存地址的範圍;多用戶多道程序系統中,採用分區分配:固定式分區,可變式分區,後者比前者分配的時候更靈活,利用程序的局部性原理,我們可以通過覆蓋、交換技術在邏輯上對內存的擴充。頁式管理克服了碎片,支持共享和保護,聯想存儲器(TLB)和塊表克服了兩次訪問主存的缺點;段式管理類似與頁式,但是頁式大小是固定不變的,而段式是又程序地址空間決定的。虛擬內存採用了不同的頁面淘汰算法來置換頁面。


        寫後感:這算是第一次認真地把一片技術博客寫完,怎麼說呢,其實我寫這篇博客花了一天多,一部分原因是因爲自己的邏輯思維沒有通,另一部分是寫着寫着就累了,有些地方寫得不是很好,希望大家見諒。不過我還是會繼續寫博客的,萬事開頭難,我相信我會越寫越順利的。加勒個油的,搖滾榮。


@教材:《操作系統原理教程(第三版)》-張麗芬 劉美華編著

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