操作系統-內存管理基礎


內存管理基礎

一、內存管理的概念

  內存管理是操作系統設計中最重要和最復雜的內容之一。計算機硬件一直在發展,內容容量也在不斷增長,但是仍然不可能將所有用戶進程和系統所需要的全部程序和數據全部放入主存中,所以操作系統必須將內存空間進行合理的化分和有效的動態分配。操作系統對內存的
划分和動態分配,就是內存管理的概念。

  有效的內存管理在多道程序設計中非常重要,不僅方便用戶使用存儲器、提高內存利用率,還可以通過虛擬技術從邏輯上擴充存儲器。

  內存管理的功能有

  ①內存空間的分配與回收,包括內存的分配和共享。
  ②地址轉換,把邏輯地址轉換成相應的物理地址。
  ③內存空間的擴充,利用虛擬技術或自動覆蓋技術,從邏輯上擴充內存。
  ④存儲保護,保證各道作業在各自存儲空間內運行,互不干擾。

  在進行具體的內存管理之前,需要了解進程運行的基本原理和要求。

  創建進程首先要將程序和數據裝入內存。將用戶原程序變成可在內存中執行的程序,通常需要以下幾個步驟

  ①編譯,由編譯程序將用戶源代碼編譯成若干個目標模塊。
  ②鏈接,由鏈接程序將編譯后形成的一組目標模塊,以及所需庫函數鏈接,形成完整的裝入模塊。
  ③裝入,由裝入程序將裝入模塊裝入內存。

  程序的鏈接有以下三種方式

  ①靜態鏈接:在程序運行之前,先將各目標模塊及它們所需的庫函數鏈接成一個完整的可執行程序,以后不再拆開。
  ②裝入時動態鏈接:將用戶源程序編譯后所得到的一組目標模塊,再裝入內存時,采用邊裝入變鏈接的方式。
  ③運行時動態鏈接:對某些目標模塊的連接,是在程序執行中需要該目標模塊時,才對她進行鏈接。其優點是便於修改和更新,便於實現對目標模塊的共享。

  內存的裝入模塊再裝入內存時,同樣有以下三種方式

  ①絕對裝入。在編譯時,如果知道程序將駐留在內存的某個位置,編譯程序將產生絕對地址的目標代碼。絕對裝入程序按照裝入模塊的地址,將程序和數據裝入內存。裝入模塊被裝入內存后,由於程序中的邏輯地址與實際地址完全相同,故不需對程序和數據的地址進行修改。絕對裝入方式只適用於單道程序環境。另外,程序中所使用的絕對地址,可在編譯或匯編時給出,也可由程序員直接賦予。

  ②可重定位裝入。在多道程序環境下,多個目標模塊的起始地址通常都是從0開始,程序中的其他地址都是相對於起始地址的,此時應采用可重定位裝入方式。根據內存的當前情況,將裝入模塊裝入到內存的適當位置。裝入時對目標程序中指令和數據的修改過程稱為重定位,地址變換通常是裝入時一次完成,所以成為靜態重定位。其特點是在一個作業裝入內存時,必須分配器要求的全部內存空間,如果沒有足夠的內存,就不能裝入,此外一旦作業進入內存后,在整個運行期間,不能在內存中移動,也不能再申
請內存空間。

  ③動態運行時裝入,也成為動態重定位,程序在內存中如果發生移動,就需要采用動態的裝入方式。動態運行時的裝入程序在把裝入模塊裝入內存后,並不立即把裝入模塊中的相對地址轉換為絕對地址,而是把這種地址轉換推遲到程序真正要執行時才進行。因此,裝入內存后的所有地址均為相對地址,這種方式需要一個重定位寄存器的支持。其特點是可以將程序分配到不連續的存儲區中;在程序運行之前可以只裝入它的部分代碼即可運行,然后在程序運行期間,根據需要動態申請分配內存;便於程序段的共享,可以向用戶提供一個比存儲空間大得多的地址空間。

  編譯后,一個目標程序所限定的地址范圍稱為改程序的邏輯地址空間。編譯程序在對一個源程序進行編譯時,總是從0號單元開始為期分配地址,地址空間中的所有地址都是相對起始地址0的,因而邏輯地址也稱為相對地址。用戶程序和程序員只需要知道邏輯地址,而內存管理
的具體機制則是透明的,這些只有系統編程人員才會涉及。不同進程可以有相同的邏輯地址,因為這些相同的邏輯地址可以映射到主存的不同位置。

  物理地址空間實質內存中物理單位的集合,它是地址轉換的最終地址,進程在運行時執行指令和訪問數據最后都要通過物理地址來存取主存。當裝入程序將可執行代碼裝入內存時,必須通過地址轉換將邏輯地址轉換成物理地址,這個過程稱為地址重定位。

  內存分配前,需要保護操作系統不受用戶進程的影響,同時保護用戶進程不受其他用戶進程的影響。通過采用重定位寄存器和界地址寄存器來實現這種保護。重定位寄存器含最小的物理地址值,界地址寄存器含邏輯地址值。每個邏輯地址值必須小於界地址寄存器。內存管理
機構動態地將邏輯地址加上重定位寄存器的值后映射成物理地址,再送交內存單元。

  當CPU調度程序選擇進程執行時,派遣程序會初始化重定位寄存器和界地址寄存器。每個地址都需要與寄存器進行核對,可以保證操作系統和其他用戶程序及數據不被該進程運行所影響。

二、覆蓋與交換

  覆蓋與交換技術是在多道程序環境下用來擴充內存的兩種方法。覆蓋技術主要用在早期的操作系統中,而交換技術則在現代操作系統中仍具有較強的生命力。

  早期的計算機系統中,主存容量很小,雖然主存中僅存放一道用戶程序,但是存儲空間放不下用戶進程的現象也經常發生,這一矛盾可以用覆蓋技術來解決。其基本思想是:由於程序運行時並非任何時候都要訪問程序和數據的各個部分,因此可以把用戶空間分成一個固定區
和若干個覆蓋區。將經常活躍的部分放在固定區,其余部分按調用關系分段。首先將那些將要訪問的段放入覆蓋區,其他段放在外存中,在需要調用時,系統再將其掉入覆蓋區,替換其中原有的段。

  交換的基本思想是:把處於等待狀態(或在CPU調度原則下被剝奪運行權利)的進程從內存移到輔存,把內存空間騰出來,這一過程又叫換出;把准備好競爭CPU運行的進程從輔存移到內存,這一過程又稱為換入。

  例如,有一個CPU采用時間片輪轉調度算法的多道程序環境。時間片到,內存管理器將剛剛執行過的進程換出,將另一進程換入到剛剛釋放的內存空間中。同時,CPU調度器可以將時間片分配給其他已在內存中的進程。每個進程用完時間片都與另一進程交換。理想情況下。內存管理器的交換過程速度足夠快,總有進程在內存中可以執行。

  有關交換需要注意以下幾個問題

  ①交換需要備份存儲,通常是快速磁盤。它必須足夠大,並且提供對這些內存影響的直接訪問。
  ②為了有效使用CPU,需要每個進程的執行時間比交換時間長,而影響交換時間的主要是轉移時間。轉移時間與所見換的內存空間成正比。
  ③如果換出進程,必須確保該進程是完全處於空閑狀態。
  ④交換空間通常作為磁盤的一整塊,且獨立與文件系統,因此使用就可能很快。
  ⑤交換通常在有許多進程運行且內存空間吃緊的時候開始啟動,而系統負荷降低就暫停。
  ⑥普通的交換使用不多,但交換策略的某些變種在許多系統中仍發揮作用。

  交換技術主要是在不同進程之間進行,而覆蓋則用於同一個程序中。由於覆蓋技術要求給程序段之間的覆蓋結構,使得其對用戶和程序員不透明,所以對於主存無法存放用戶程序的矛盾,現在操作系統是通過虛擬內存技術來解決的,覆蓋技術則已成為歷史;而交換技術在現代操作系統中仍具有較強的生命力。

三、連續分配管理方式

  連續分配方式,是指為一個用戶程序分配一個連續的內存空間。它主要包括單一連續分配、固定分區分配和動態分區分配。

單一連續分配

  內存在此方式下分為系統區和用戶區,系統區僅提供給操作系統使用,通常在低地址部分;用戶區是為用戶提供的除系統外的內存空間。這種方式無需進行內存保護。這種方式的優點是簡單、無外部碎片,可以采用覆蓋技術,不需要額外的技術支持。缺點是只能用於單用戶、單任務的操作系統中,有內部碎片,存儲器的利用率極低。

固定分區分配

  固定分區分配是最簡單的一種多道程序存儲管理方式,它將內存用戶空間划分為若干個固定大小的區域,每個分區只裝入一道作業。當有空閑分區時,便可以再從外存的后備隊列中選擇適當大小的作業裝入該分區。如此循環。固定分區分配在划分分區時,有兩種不同的方法:
  ①分區大小相等:用於利用一台計算機去控制多個相同對象的場合。
  ②分區大小不等:划分為含有多個較小的分區、適量的中等分區及少量的大分區。

  為了便於內存分配,通常將分區按大小排隊,並為之建立一張分區使用表,其中個表項包括每個分區的起始地址、大小及狀態。當有用戶程序要裝入時,便檢索該表,已找到合適的分區給與分配並將其狀態置為“已分配“。未找到合適分區則拒絕為該用戶程序分配內存。

  這種分區方式存在兩個問題:一個程序可能太大而放不進任何一個分區中,這是用戶不得不使用覆蓋技術來使用內存空間;二是主存利用率低,當程序小於固定分區大小時,也占用了一個完整的內存分區空間,這樣分區內部有空間浪費。這種現象成為內部碎片。

  固定分區可用於多道程序設計最簡單的存儲分配,但不能實現多進程共享一個主存區,所以存儲空間利用率低。固定分區分配很少用於現在通用的計算機,但在某些用於控制多個相同對象的控制系統中仍發揮着一定的作用。

動態分區分配

  動態分區分配又稱為可變分區分配,是一種動態划分內存的分區方法。這種分區方法預先將內存划分,而是在進程裝入內存時,根據進程的大小動態的建立分區,並使分區的大小正好適合進程的需要。因此系統中分區的大小和數目是可變的。

  動態分區在開始分配時是很好的,但是之后會導致內存中出現許多小的內存塊。隨着時間的推移,內存中會產生越來越多的碎片,內存的利用率隨之下降。這種現象稱之為外部碎片現象,指在所有分區外的存儲空間會變成越來越多的碎片,這與固定分區中的內部碎片正好相
對。克服外部碎片可以通過緊湊技術來解決,就是操作系統不時地對進程進行移動和整理。

  但是這需要動態定位的支持,且相對費時。緊湊的過程實際上類似於windows系統中的磁盤整理程序,只不過后者是對外存空間的緊湊。

  在進程裝入或換入主存時。如果內存中有多個足夠大的空閑塊,操作系統必須確定分配那個內存塊給進程使用,這就是動態分區的分配策略。考慮以下幾種算法:

1)首次適應算法:空閑分區以地址遞增的次序鏈接。分配內存時順序查找,找到大小能滿足要求的第一個空閑分區。
2)最佳適應算法:空閑分區按容量遞增形成分區鏈,找到第一個能滿足要求的空閑分區。
3)最壞適應算法:有稱最大適應算法,空閑分區以容量遞減次序鏈接。找到第一個能滿足要求的空閑分區,也就是挑選最大的分區。
4)臨近適應算法:又稱循環首次適應算法,由首次適應算法演變而成。不同之處是分配內存時從此查找結束的位置開始繼續查找。

  在這幾種方法中,首次適應算法不僅是最簡單的,而且通常是最好和最快的。在UNIX系統的最初版本中,就是使用首次適應算法為進程分配內存空間,其中使用數組的數據結構(而非鏈表)來實現。不過,首次適應算法會使得內存的低地址部分出現很多小的空閑分區,而每次分配查找時,都要經過這些分區。

  臨近適應算法試圖解決這一問題,但實際上,它常常會導致在內存的末尾分配空間,分裂成小碎片。它通常比首次適應算法的結果要差。

  最佳適應算法雖然稱為最佳,但是性能通常很差,因為每次最佳的分配會留下最小的內存塊,它會產生最多的碎片。

  最壞適應算法與最佳適應算法相反,選擇最大的可用塊,這看起來最不容易產生碎片,但是卻把最大的連續內存划分開,會很快導致沒有可用的大的內存塊,因此性能非常差。

  以上內存分區管理方法有一共同特點,即用戶進程在主存中都是連續存放的。

四、非連續分配管理方式

  非連續分配方式允許一個程序分散的裝入不相鄰的內存分區中,根據分區的大小是否固定分為分頁存儲管理方式和分段存儲管理方式。

  分頁存儲管理方式中,又根據運行作業時是否要把作業的所有頁面都裝入內存才能運行分為基本分頁存儲管理和請求分頁存儲管理方式。

  固定分區會產生內部碎片,動態分區會產生外部碎片,兩種技術對內存的利用率都比較低。我們希望內存的使用能盡量避免碎片的產生,這就引出了分頁思想:把主存空間划分為大小相等且固定的塊,塊相對較小,作為主存的基本單位。每個進程也以塊為單位進行划分,進程在執行時,以塊為單位逐個申請主存中的塊空間。

分頁存儲的幾個基本概念

  頁面和頁面大小。進程中的塊稱為頁,內存中的塊稱為頁框。外存也以同樣單位划分,直接稱為塊。進程在執行時需要申請主存空間,就是要為每個頁面分配主存中的可用頁框,這就產生了頁和頁框的一一對應。為了方便地址轉換,頁面大小應是2的整數冪。同時頁面大小應當適中。如果頁面太小,會使進程的頁面數過多,這樣頁表就過長,占用大量內存,而且也會增加硬件地址轉換的開銷,降低頁面換入換出的效率。頁面過大又會使頁面碎片過大,降低內存利用率。所以頁面的大小應該適中,考慮到空間效率和時間效率。

  地質結構。分頁存儲管理的地質結構包含兩部分:前一部分為頁號,后一部分為頁內偏移量W。地址長度為32位,其中0~11為頁內地址,即每頁大小為4kB;12~31位為頁號,地址空間最多允許有2 20頁。

  頁表。為了便於在內存中找到進程的每個頁面所對應的物理塊,系統為每個進程建立一張頁表,記錄頁面在內存中對應的物理塊號,頁表一般存放在內存中。在配置了頁表后,進程執行時,通過查找該表,即可找到每頁在內存中中的物理塊號。可見,頁表的作用是實現從頁號到物理塊號的地址映射。

基本地址變換機構

  地址變換機構的任務是將邏輯地址中的頁號轉換為內存中物理塊號,地址變換是借助於頁表實現的。在系統中通常設置一個頁表寄存器PTR,存放頁表在內存的初值和頁表長度。邏輯地址到物理地址的變換過程如下:

  ①地址變換機構自動將有效地址分為頁號和頁內偏移量兩部分,再用頁號去檢索頁表。在執行檢索之前,先將頁號與頁表長度比較,如果頁號大於或等於頁表長度,則表示地址越界並中斷。
  ②若未越界,則將頁表始址與頁號和頁表項長度的乘積相加,便得到該表項在頁表中的位置,於是可從中得到該頁的物理塊號。
  ③與此同時,在將有效地址中的頁內偏移量送入物理地址寄存器的塊內地址字段中。

  以上整個地址變換過程均是由硬件自動完成的。

分頁管理方式存在的兩個主要問題

  ①每次訪存操作都需要進行邏輯地址到物理地址的轉換,地址轉換過程必須足夠快,否則訪存速度會降低;

  ②每個進程引入了頁表,用於存儲映射機制,頁表不能太大,否則內存利用率會降低。

具有快表的地址變換機構

  由上面介紹的地址變換過程可知,若頁表全部放在內存中,則要存取一個數據或一條指令至少要訪問兩次內存:一次是訪問頁表,確定要存取的數據或指令的物理地址,第二次才根據該地址存取數據或指令。顯然,這種方法比通常執行指令的速度慢了一半。

  為此,在地址變換機構中增設了一個具有並行查找能力的高速緩沖存儲器——快表,又稱聯想寄存器TLB,用以存放當前訪問的若干頁表項。與此對應,主存中的頁表也常稱為慢表。

  在具有快表的分頁機制中,地址的變換過程:

  ①CPU給出有效地址后,由硬件進行地址轉換,並將頁號送入高速緩存寄存器,並將此頁號與快表中的所有頁號同時進行比較。
  ②如果有找到匹配的頁號,說明索要訪問的頁表項在快表中,則可以直接從中讀出該頁對應的頁框號,送到屋里地址寄存器。這樣存取數據可以直接一次訪存實現。
  ③如果沒有找到,則需要訪問主存中的頁表,在讀出頁表項后,應同時將其存入快表中,以供后面可能的再次訪問。但是如果快表已滿,就必須按照一定的算法對其中舊的頁表項進行替換。注意,有些處理器設計為快表和主存同時查找,如果在快表中匹配成功則終止主存中的查找。

  一般快表的命中率可以達到90%,這樣,分頁帶來的速度損失就降到10%。快表的有效性是基於著名的局部性原理。這在后面的虛擬內存中將會具體討論。

四、兩級頁表

  第二個問題:由於引入了分頁管理,進程在執行時不需要將所有頁調入內存頁框中,而只要將保存有映射關系的頁表調入內存即可。但是我們仍然需要考慮頁表的大小。如果頁表太大,肯定是降低了內存利用率的;從另一方面來說,程序所有的頁表項也並不需要同時保存在內存中,因為在大多數情況下,映射所需要的頁表都再頁表的同一個頁面中。

  我們將頁表映射的思想進一步延伸,就可以得到二級分頁:將頁表的10頁空間也進行地址映射,建立上一級頁表,所以上一級頁表只需要一頁就足夠。在進程執行時,只需要將這一頁上一級頁表調入內存即可,進程的頁表和進程本身的頁面,可以在后面的執行中再調入內存。

  分頁管理方式是從計算機的角度考慮設計的,以提高內存的利用率,提升計算機的性能,且分頁通過硬件機制實現,對用戶完全透明;而分段管理方式的提出則考慮了用戶和程序員,以滿足方便編程、信息保護和共享、動態增長及動態鏈接等多方面的需要。

分段

  段是系統按照用戶進程中的自然段划分邏輯空間。例如,用戶進程由主程序、兩個字程序、棧和一段數據組成,於是可以把這個用戶進程划分為5個段,每段從0開始編址,並采用一段連續的地址空間(段內要求連續,段間不要求連續),其邏輯地址由兩部分組成:段號與段
內偏移量,分別記為S、W。

  段號為16位,段內偏移量為16位,則一個作業最多可有2 16=65536個段,最大段長64KB。在頁式系統中,邏輯地址的頁號和頁內偏移量對用戶是透明的;但在段式系統中,段號和段內偏移量必須由用戶顯示提供,在高級程序設計語言中,這個工作由編譯程序完成。

段表

  每個進程都有一張邏輯空間與主存空間映射的段表,其中每一段表項對應進程的一個段,段表項紀錄路該段在內存中的起始地址和段的長度。

  在配置了段表后,執行中的進程可通過查找段表,找到每個段所對應的內存區。可見,段表用於實現從邏輯端段到物理內存區的映射。

地址變換機構

  為了實現進程從邏輯地址到物理地址的變換功能,在系統中設置了段表寄存器,用於存放段表始址和段表長度TL。在進行地質變換時,系統將邏輯地址中的段號,與段表長度TL比較。若段號大雨段表長度,表示短號太大,訪問越界,於是產生越界中斷信號。若未越界,則根
據段表的始址和該段的段號,計算出該段對應段表項的位置,從中讀出該段在內存中的起始地址。然后,在檢查段內地址W是否超過該段的段長SL。若超過,同樣發出越界中斷信號。若未越界,則將該段的基址d與段內地址相加,即可得到要訪問的內存物理地址。頁式存儲管理能有效的提高內存利用率,而分段存儲管理能反應程序的邏輯結構並有利於段的共享。如果將這兩種存儲管理方法結合起來,就形成了段頁式存儲管理方式。

  在段頁式系統中,作業的地址空間首先被分成若干個邏輯段,每段都有自己的段號,然后再將每一段分成若干個大小固定的頁。對內存空間的管理仍然和分頁存儲管理一樣,將其分成若干個和頁面大小相同的存儲塊,對內存的分配以存儲塊為單位。

  在段頁式系統中,作業的邏輯地址分為三部分:段號、頁號和頁內偏移量。為了實現地址變換,系統為每個進程建立一張段表,而每個分段有一張頁表。段表表項中至少包括段號、頁表長度和頁表起始地址,頁表表項中至少包括頁號和塊號。此外,系統中還應有一個段表寄存器,指出作業的段表起始地址和段表長度。

  在進行地址變換時,首先通過段表查到頁表起始地址,然后通過頁表找到幀號,最后形成物理地址。進行一次訪問實際需要三次訪問主存,這里同樣可以使用快表提供加快速度,其關鍵字由段號、頁號組成,值是對應的頁幀號和保護碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM