個人操做系統複習——存儲器管理

  上篇博客介紹了處理機調度的相關知識——個人操做系統複習——處理機調度,本篇開始講跟處理機打交道最多的計算機部件——存儲器。存儲器包括常說的內存和外存。存儲器管理,通常指的是內存管理。外存也屬於存儲器,不過應該算做文件管理。html

1、存儲器層次分類

  存儲器按存儲層次分能夠分爲三類,分別是寄存器、主存、輔存。寄存器位於CPU內,主存又稱內存,輔存即硬盤。仔細劃分的話,主存還能夠分爲高速緩存、主存、磁盤緩存。以下圖所示,層次越往上,存儲介質訪問速度越快,價格越貴、相對存儲容量也越貴。寄存器和主存這裏大概說一說,輔存(外存)就留到文件系統的時候再說。算法

  

  (1)寄存器

  寄存器位於CPU內,是CPU的組成部分。它是計算機系統內CPU訪問速度最快的存儲部件,徹底能與CPU協調工做。不過價格太貴,只能作得很小。寄存器是用來存放系統最常訪問的數據,如,指令寄存器用來存放從內存讀到的正在執行的指令,程序計數器存放下一條指令所在單元的地址。其本質就是用來存放供CPU最頻繁訪問的一批數據。寄存器就是爲了解決CPU訪問主存速度過慢的問題。一般,CPU從主存讀取數據,放入寄存器內,以便頻繁訪問。緩存

  (2)主存

  主存即內存。CPU能夠經過指令直接存取主存中的數據,因此CPU對主存的訪問速度也很快,不過這個速度也遠低於CPU的執行速度。爲了解決這個問題,引入了寄存器和高速緩存。高速緩存是什麼?高速緩存也是屬於內存,不過它與一般的主存的實現形式不一樣,它通常是由靜態存儲芯片(SRAM)組成,訪問速度比主存高得多, 接近於CPU的速度。而主存一般使用動態MOS隨機讀寫存儲器DRAM組成,速度比SRAM快得多。高速緩存的做用就是存放主存中一些常常被訪問的信息。磁盤緩存的本質就是主存劃分的一個小區域,爲了減小CPU透過I/O讀取磁盤機的次數,提高磁盤I/O的效率,用一塊區域來儲存存取較頻繁的磁盤內容。數據結構

 

2、程序的裝入和連接

  程序裝入就是把程序和數據放入內存。程序也不是一開始就有的。這裏指的程序是最終在內存中運行的模塊——裝入模塊。那麼一份源代碼是怎麼變成可運行的程序的呢?學過C、C++的同窗對這個最瞭解。首先是把源代碼用編譯程序編譯成目標模塊,每一份源代碼文件對應一個目標模塊。而後用連接程序將目標模塊和程序所須要的庫函數連接起來,變成一個可運行的程序。這個可運行的程序,實質是編譯連接後的機器指令,CPU能夠運行這些機器指令。程序運行時,裝入模塊將其放入內存並運行。其中,將這些機器指令何其指向的資源裝入內存有3種方式:併發

  (1)裝入:

    1)絕對裝入方式(Absolute Loading Mode)函數

  程序中使用的地址是直接指向內存的絕對地址,那麼在把程序裝入內存的時候,不須要對程序地址作任何修改,這種裝入方式就叫作絕對裝入方式。絕對裝入方式只能將程序裝入到內存中指定的位置,它只適合單道處理環境,這樣就不會有內存衝突了。優化

    2)可重定位裝入方式(Relocation Loading Mode)ui

  可重定位裝入方式指的是,將程序裝入內存的時候,將程序地址都相對於內存當前地址偏移。這時程序中的地址都是相對地址。值得注意的是,裝入時對程序中指令和數據地址的修改過程叫作重定位。spa

    3)動態運行時裝入方式(Dynamic Run-time Loading)操作系統

  若是程序在運行時位置須要改變,應該採用動態運行時裝入方式。動態運行時裝入方式指的是程序中的相對地址並不在裝入時就轉換成內存中的絕對地址,而是等到真正運行的時候纔會轉換。

  (2)連接:

  與程序裝入相對應的是程序的連接方式。程序的連接方式也有3種方式,分別是靜態連接方式、裝入時動態連接和運行時動態連接。分別對應的是程序連接時的3個時間。其中靜態連接是程序的目標模塊在裝入以前就連接好,而裝入時動態連接,顧名思義,就是目標模塊實在裝入內存的時候動態的進行連接,這種方式連接的程序的目標模塊是分開存放的,若一個目標模塊須要連接給其餘多個模塊是很是方便的。而在靜態連接方式中要實現這個功能,須要其餘多個模塊都含有該模塊的拷貝。

 

3、內存分配方式——連續分配方式

  將內存分配給程序,最典型的方式就是將一個連續的內存空間分配給程序,這就是連續分配方式。這種分配方式細分能夠分爲單一連續分配、固定分區分配、動態分區分配和動態重定位分區分配。須要瞭解的是,前面的程序裝入內存的過程就是典型的內存分配。就是說,內存的分配一般多是動態,在程序運行過程當中,一般伴隨着動態的內存建立和內存回收,其中還涉及到不少緩存、優化之類的策略。在各類內存分配和回收的過程當中,會產生不少空餘碎片。內存分配就是要儘量利用內存空間,避免內存浪費。

  (1)單一連續分配

  這種分配方式就是簡單的把內存分爲系統區和用戶區,系統區給操做系統用,用戶區給用戶用。這種分配方式很是簡單,並未考慮多用戶內存衝突和多任務內存衝突的狀況,因此只適用於單用戶、單任務的OS。值得注意的是,系統區一般是分配在內存的低址部分。

  (2)固定分區分配

  這種分配方式就是將內存劃分爲若干固定大小的區域,區域的大小是事先劃分好的,每一個區域裝入一道做業、程序,這樣多任務內存衝突的問題就解決了。這種劃分方法適用於多道批處理系統——多任務併發的狀況。可是,因爲每一個分區大小固定,存儲空間的浪費是必然的。

  (3)動態分區分配

  這種分配方式就是根據進程的實際須要,動態的分配內存空間。這種分配方式有3個問題須要注意。一、須要有一種數據結構來描述空閒分區和已分配分區的狀況。二、須要按照必定的分配算法從空閒分區中選擇空間來分配。三、須要有合適的分區分配和內存回收操做:

    1)描述空閒分區的數據結構:

    有2種數據結構能夠描述空閒分區的數據結構,分別是空閒分區表和空閒分區鏈。其中,分區表很容易理解,分區鏈指的是經過在空閒分區的首尾設置2個指向其餘空閒分區的指針,造成一個空閒分區的鏈,用來記錄空閒的分區。

    2)分區分配算法:

    • 首次適應算法(first fit):分區鏈以地址遞增的次序連接;分配內存時,從鏈首開始,查找到一個大小能知足要求的空閒分區就中止。這個算法說白了就先分配內存的低址部分,再分配高址部分。
    • 循環首次適應算法(next fit):這個分配算法與首次適應算法的區別在於,它分配內存時,不是從鏈首開始查找,而是從上次找到的空閒分區的下一個分區開始查找。
    • 最佳適應算法(best fit): 分區鏈以從小到大的順序連接;分配內存時,從鏈首開始,查找到一個能知足要求的空閒分區就中止。
    • 最壞適應算法(worst fit): 分區鏈以從大到小的順序鏈接;與最佳適應算法相反,每次都挑最大的空閒區來分配。
    • 快速適應算法(quick fit): 將空閒區根據大小進行分類,每一種類別單獨設立一個鏈表。同時,用一個管理索引表來管理這些鏈表。那麼分配內存的時候只須要查詢管理索引表就好了,無需遍歷鏈表,速度很是快。缺點是,這個算法須要一直維護着鏈表和管理索引表,須要必定系統開銷。

    3)內存分配和回收:

    在分配空閒分區的時候,值得注意的是,一般空閒分區會有一個「不可再分割的剩餘分區大小」的屬性,規定了,當空閒分區所剩屬性小於它的時候,分區不容許再繼續分割,分區也將從空閒分分區鏈表中移除。

    內存回收的時候,值得注意的是,若回收的內存區與某個空閒分區相鄰接,那麼須要將它們合併。不然,須要爲回收區創建新的空閒分區。 

    4)夥伴系統:

    咱們知道1G的內存有220個字節,有224個字。那麼根據指數,最多分爲24個空閒分區鏈表。假設一個應用程序申請2MB的內存,2MB即215個字的大小,這時候查找大小爲215的空閒分區鏈表,若找不到,那麼查找大小爲216的空閒分區鏈表,若216的空閒分區鏈表存在,那麼把它分紅2個,一個分配給請求,另外一個分配爲215的空閒分區鏈表,若若216的空閒分區鏈表不存在,那麼繼續日後查找,以此類推。

  (4)可重定位分區分配

    因爲程序、資源間會有不少碎片,浪費了內存空間,可重定位分區分配就是爲了解決這個問題,它能夠直接移動內存中的程序、資源,使內存變得緊湊,同時也不影響程序的正常運行。可重定位分區分配要求程序的裝入方式是動態運行時裝入方式。程序裝入內存後,全部地址仍舊是相對地址,直到運行時纔會轉變爲絕對地址。程序在寄存器中有一個重定位寄存器,用來存放程序在硬盤中的實際地址的首地址。那麼將程序在內存中的絕對地址移動,只須要移動後,改變重定位寄存器的值便可。這咱們常常用的「磁盤碎片清理」就是同樣的效果。

  (5)對換

    對換是一個須要瞭解一下的概念。還記得前面咱們講進程調度的時候,有一個特殊的調度類型,叫作中級調度。中級調度就是讓暫時不能運行的進程掛起,釋放內存資源,並把它們調到外存上去等待,這種操做,在內存看來,就叫對換。以進程爲單位的對換叫進程對換。對換的狀況下,外存中必須分配必定的區域用來存放對換的內存資源,叫作對換區。這個對換區本質是虛擬存儲器,這個後面會講。

 

4、內存分配方式——離散分配方式

  連續的分配方式會產生不少碎片。離散的分配方式是將進程、資源裝入不相鄰的多個分區的內存分配方式。這種分配方式按照分配的單位是「頁」仍是「段」,分爲分頁存儲管理、分段存儲管理以及段頁式存儲管理。

 (1)分頁存儲管理

  分頁存儲管理是根據程序做業中的「頁」爲單位離散分配內存的管理。

  1)頁面(頁)。

  分頁存儲管理的內存分配單位是頁。什麼是頁?頁就是一段指定大小的內存塊。分頁存儲管理就是按照必定大小把進程的邏輯地址空間分紅若干份,每一份就是一個頁,把他們編號。而後按照頁的大小把內存分爲若干物理塊,並編號。頁的大小一般是512B到8KB之間。

  2)頁表。

  每個進程都有一張頁表,用來記錄進程的頁號對應的物理塊號。進程運行時,CPU會根據程序的邏輯地址和頁號大小從頁表找到實際的物理塊和實際的物理地址。頁表是常常被CPU訪問的,CPU常常須要先訪問頁表再根據頁表的地址訪問內存,因此通常會設置一個「聯想寄存器」,又稱「塊表」,存放最近頻繁訪問的頁表。若是系統的內存特別大,頁表中頁面的邏輯地址就會特別大,就須要用多層的頁表結構來對應物理塊號。這種狀況下,CPU會根據程序的邏輯地址和頁面大小從多層的外部頁表找到指定的頁表,再從頁表中找到實際的物理塊和物理地址。

(2)分段存儲管理

  分段存儲管理是根據程序做業中的「段」爲單位離散分配內存的管理。

  1)段。

  段指的是程序、做業中的一組邏輯信息。例如:全局變量能夠設爲一個段;每一個函數的局部變量能夠設爲一個段;每一個函數的代碼部分能夠設置爲一個段。這樣作有什麼意義呢?至關於將程序中的這種邏輯信息根據大小離散的存儲在內存中,而對於邏輯信息自己而言,他們在內存中是連續的,不會被分割的,這樣有利於對邏輯信息的處理,如信息共享、信息保護等。

  2)段表。

  與頁表相似的,每一個進程都有一張段表,用來記錄程序中每一個段對應的物理位置。段表中每一個記錄都記錄了段的物理地址和段的長度。一樣,因爲段表常常須要被訪問,有些系統會把段表放在寄存器中。

  (PS:值得注意的是,運行時動態連接要求內存使用分段存儲管理。)

(3)段頁式存儲管理

  段頁式存儲管理是根據「段」爲單位,再將「段」細分爲「頁」,以這個爲單位離散分配內存的管理。原理與分頁、分段存儲管理相似。  

 

5、虛擬存儲器管理

   對於內存的連續分配方式,上文有一個「對換」的概念,就是將暫時不用的內存資源從內存中移出,放到外存的對換區中。當須要該內存資源的時候,須要及時可以把該內存資源從外存中移入內存。這裏的對換區其實就是虛擬存儲器。講到虛擬存儲器有須要瞭解一下程序執行的局部性原理,總結下來就是:

  • 程序的執行過程當中,大部分的指令是執行一次或不多執行的,CPU主要是在執行一小部分指令。
  • 程序的執行過程當中,大部分資源是不多被訪問的。

  因此,程序一次性裝入內存,而實際上大部份內存資源是被浪費的。基於這種狀況,不必把全部資源都一次性裝入內存。僅須要將程序當前須要的運行的段(頁)裝入內存便可。若是程序運行時訪問到內存中不存在的段(頁),這種現象叫「缺段」(卻頁),這時候須要根據必定算法從外存的虛擬存儲區將缺失的資源當即裝入內存。

  這裏有一個補充知識,見http://zhidao.baidu.com/question/86215203.html:

   至於頁表的問題是這樣的,在系統初始化時,是直接對物理內存進行訪問的,不通過頁表,這是的工做模式叫實模式,等頁表在內存中創建好了,再切換的保護模式,在保護模式就出現了虛擬地址向物理地址轉譯的過程了。 

  CPU有兩種工做模式,一個是實模式,就是直接訪問物理內存,不分頁的。另外一個是保護模式,就是分頁的,並且存在虛擬地址。保護模式下又有特權模式和用戶模式兩種。關係是這樣子的。

  我給你講,只要發生缺頁中斷,就會陷入內核,只是就進入了特權模式,控制權交給了操做系統,這一系列過程都是硬件完成的。至於換頁使軟件完成的,就是操做系統負責調頁。MMU只是負責把虛擬地址轉譯成物理地址,他只能作這個,純硬件實現的。操做系統有調頁算法,就是在空閒的頁找出來一個,把須要的內容從磁盤讀出來,放到內存裏,而後讓進程從新運行那條指令。一切繼續,就像沒有缺頁過同樣。若是沒有空閒的,就把最不常用的一頁替換掉。

 

 參考:《計算機操做系統(湯子瀛)》

相關文章
相關標籤/搜索