1. 程式人生 > >作業系統 記憶體管理 知識點

作業系統 記憶體管理 知識點

目錄:

地址的動靜態重定位

記憶體分配演算法

程式的連結和裝入(靜態和動態)

邏輯地址和實體地址

虛擬記憶體,實際記憶體,內部外部碎片

地址的重定位
程式執行時,必須將地址空間變為絕對地址才能訪問系統分配的記憶體地址重定位:作業系統把使用者程式指令中的相對地址變換成為所在儲存中的絕對地址的過程地址重定位實現了:從邏輯地址到實體地址的轉換按照重定位時機分類:靜態重定位、動態重定位
  • 地址的靜態重定位
定義:在程式執行之前,為使用者程式實行了地址重定位工作一般由作業系統中的重定位裝入程式完成重定位裝入程式的輸入:使用者把自己的作業連結裝配成一個相對於 0 編址的目標程式過程:重定位裝入程式根據當前記憶體的分配情況,按照分配區域的起始地址逐一調整目標程式指令中的地址部分。目標程式在經過重定位裝入程式加工之後,不僅進入到分配給自己的絕對地址空間中,而且程式指令中的地址部分全部進行了修正,反映出了自己正確的儲存位置,保證了程式的正確執行
特點:在裝入前實現調整地址要有標識每次裝入都要進行定位裝入後地址不再改變(靜態)
  • 地址的動態重定位
定義:在程式執行定址時進行重定位,訪問地址時,通過地址變換機構改變為記憶體地址使用者程式原封不動的裝入記憶體,執行時再完成地址的定位工作動態重定位需要硬體的支援,要求系統中配備定位暫存器加法器特點:程式可裝入任意記憶體區域(不要求佔用連續的記憶體區)只裝入部分程式程式碼即可執行改變系統時不需要改變程式(程式佔用的記憶體空間動態可變,只需要改變定位暫存器中的值即可)程式可方便共享
  1. 為了保證CPU執行指令時可正確訪問儲存單元,需將使用者程式中的邏輯地址轉換為執行時由機器直接定址的實體地址,這一過程稱為地址對映。
  2. 記憶體分配方法:
最優適應演算法:通常將空閒區按長度遞增順序排列。查詢時總是從最小一個空閒區開始,直到找到滿足要求的分割槽為止。此演算法保證不會分割一個更大的區域,使得裝入大作業的要求容易得到滿足。補充:最先適應演算法:通常將空閒區按地址從小到大排列。查詢時總是從低地址開始,可使高地址儘量少用,以保持一個大空閒區,有利於大作業的裝入;缺點是記憶體低地址和高地址兩端的分割槽利用不平衡,回收分割槽較麻煩。空閒區分割給作業使用,其優點是使剩下的空閒區不致於太小,這樣有利於中小型作業,但不利於大作業。這些都屬於可變分割槽分配演算法,當然還有下次適應分配演算法和快速適應分配演算法。注:這些演算法理解即可。最壞適應演算法
通常將空閒區按長度遞減順序排列 。查詢時從最大的一個空閒區開始,總是挑選一個最大的
  1. 一般情況下虛擬記憶體的大小大於實體記憶體與外部儲存的大小總和。
比如對於一臺80x86上執行的32位Linux,其可定址的實體地址空間為4GB,虛存大小上限為 4GB * 程序數上限。
  1. 記憶體管理
記憶體管理的功能有:
  • 記憶體空間的分配與回收:由作業系統完成主儲存器空間的分配和管理,使程式設計師擺脫儲存分配的麻煩,提高程式設計效率。
  • 地址轉換:在多道程式環境下,程式中的邏輯地址與記憶體中的實體地址不可能一致,因此儲存管理必須提供地址變換功能,把邏輯地址轉換成相應的實體地址。
  • 記憶體空間的擴充:利用虛擬儲存技術或自動覆蓋技術,從邏輯上擴充記憶體。
  • 儲存保護:保證各道作業在各自的儲存空間內執行,.互不干擾。
在進行具體的記憶體管理之前,需要了解程序執行的基本原理和要求。

程式裝入和連結

建立程序首先要將程式和資料裝入記憶體。將使用者源程式變為可在記憶體中執行的程式,通常需要以下幾個步驟:
  • 編譯:由編譯程式將使用者原始碼編譯成若干個目標模組。
  • 連結:由連結程式將編譯後形成的一組目標模組,以及所需庫函式連結在一起,形成一個完整的裝入模組。
  • 裝入:由裝入程式將裝入模組裝入記憶體執行。
這三步過程如圖3-1所示。
圖3-1  對使用者程式的處理步驟程式的連結有以下三種方式:
  • 靜態連結:在程式執行之前,先將各目標模組及它們所需的庫函式連結成一個完整的可執行程式,以後不再拆開。
  • 裝入時動態連結:將使用者源程式編譯後所得到的一組目標模組,在裝入記憶體時,釆用邊裝入邊連結的連結方式。
  • 執行時動態連結:對某些目標模組的連結,是在程式執行中需要該目標模組時,才對它進行的連結。其優點是便於修改和更新,便於實現對目標模組的共享。
記憶體的裝入模組在裝入記憶體時,同樣有以下三種方式:1) 絕對裝入。在編譯時,如果知道程式將駐留在記憶體的某個位置,編譯程式將產生絕對地址的目的碼。絕對裝入程式按照裝入模組中的地址,將程式和資料裝入記憶體。由於程式中的邏輯地址與實際記憶體地址完全相同,故不需對程式和資料的地址進行修改。絕對裝入方式只適用於單道程式環境。另外,程式中所使用的絕對地址,可在編譯或彙編時給出,也可由程式設計師直接賦予。而通常情況下在程式中釆用的是符號地址,編譯或彙編時再轉換為絕對地址。2) 可重定位裝入。在多道程式環境下,多個目標模組的起始地址通常都是從0開始,程式中的其他地址都是相對於起始地址的,此時應釆用可重定位裝入方式。根據記憶體的當前情況,將裝入模組裝入到記憶體的適當位置。裝入時對目標程式中指令和資料的修改過程稱為重定位,地址變換通常是在裝入時一次完成的,所以又稱為靜態重定位,如圖3-2(a) 所示。
圖3-2  重定向型別靜態重定位的特點是在一個作業裝入記憶體時,必須分配其要求的全部記憶體空間,如果沒有足夠的記憶體,就不能裝入該作業。此外,作業一旦進入記憶體後,在整個執行期間不能在記憶體中移動,也不能再申請記憶體空間。3) 動態執行時裝入,也稱為動態重定位,程式在記憶體中如果發生移動,就需要釆用動態的裝入方式。裝入程式在把裝入模組裝入記憶體後,並不立即把裝入模組中的相對地址轉換為絕對地址,而是把這種地址轉換推遲到程式真正要執行時才進行。因此,裝入記憶體後的所有地址均為相對地址。這種方式需要一個重定位暫存器的支援,如圖3-2(b)所示。動態重定位的特點是可以將程式分配到不連續的儲存區中;在程式執行之前可以只裝入它的部分程式碼即可投入執行,然後在程式執行期間,根據需要動態申請分配記憶體;便於程式段的共享,可以向用戶提供一個比儲存空間大得多的地址空間。

邏輯地址空間與實體地址空間

編譯後,每個目標模組都是從0號單元開始編址,稱為該目標模組的相對地址(或邏輯地址)。當連結程式將各個模組連結成一個完整的可執行目標程式時,連結程式順序依次按各個模組的相對地址構成統一的從0號單元開始編址的邏輯地址空間。使用者程式和程式設計師只需知道邏輯地址,而記憶體管理的具體機制則是完全透明的,它們只有系統程式設計人員才會涉及。不同程序可以有相同的邏輯地址,因為這些相同的邏輯地址可以對映到主存的不同位置。實體地址空間是指記憶體中物理單元的集合,它是地址轉換的最終地址,程序在執行時執行指令和訪問資料最後都要通過實體地址從主存中存取。當裝入程式將可執行程式碼裝入記憶體時,必須通過地址轉換將邏輯地址轉換成實體地址,這個過程稱為地址重定位。

記憶體保護

記憶體分配前,需要保護作業系統不受使用者程序的影響,同時保護使用者程序不受其他使用者程序的影響。通過釆用重定位暫存器和界地址暫存器來實現這種保護。重定位暫存器含最小的實體地址值,界地址暫存器含邏輯地址值。每個邏輯地址值必須小於界地址暫存器;記憶體管理機構動態地將邏輯地址與界地址暫存器進行比較,如果未發生地址越界,則加上重定位暫存器的值後對映成實體地址,再送交記憶體單元,如圖3-3所示。當CPU排程程式選擇程序執行時,派遣程式會初始化重定位暫存器和界地址暫存器。每一個邏輯地址都需要與這兩個暫存器進行核對,以保證作業系統和其他使用者程式及資料不被該程序的執行所影響。
  1. 虛擬儲存器
虛擬儲存器基於區域性性原理,在程式執行時,可以將程式的一部分裝入記憶體,而將其餘部分留在外存,就可以啟動程式執行。在程式執行過程中,當訪問的資訊不在記憶體時,由作業系統將所需的部分調入記憶體,然後繼續執行。另一方面,作業系統將記憶體中暫時不使用的內容換出到外存上,從而騰出空間存放將要調入的資訊。可行性基礎虛存的可行性基礎是計算機中著名的區域性性原理。 區域性性原理表現在以下兩個方面: ☞ 時間區域性性:如果程式中的某條指令一旦執行,不久之後該指令可能再次執行;如果某資料被訪問過,不久之後該資料可能再次被訪問。產生時間區域性性的典型原因是程式中存在著大量的迴圈操作。 ☞ 空間區域性性:一旦程式訪問了某個儲存單元,在不久之後,其附近的儲存單元也將被訪問,即程式在一段時間內所訪問的地址,可能集中在一定的範圍內,這是因為指令通常是順序存放、順序執行的,資料也一般是以向量、陣列、表等形式聚簇儲存的。實現虛存最主要的技術是(部分對換)。虛擬記憶體的特徵是:1.虛擬擴充 即不是物理上而是邏輯上擴充了記憶體容量2.部分裝入 即每個作業不是全部一次性地裝入記憶體,而是只裝入一部分3.離散分配 即不必佔用連續的記憶體空間,而是“見縫插針”4.多次對換 即所需的全部程式和資料要分成多次調入記憶體計算機系統的虛擬儲存器,其最大容量取決於機器的地址結構(即頁面大小)及系統的邏輯地址結構,而實際容量則取決於系統中內、外存容量總和。
  1. 內部碎片和外部碎片
在記憶體管理中,內部碎片是已經被分配出去的的記憶體空間大於請求所需的記憶體空間。外部碎片是指還沒有分配出去,但是由於大小太小而無法分配給申請空間的新程序的記憶體空間空閒塊。固定分割槽存在內部碎片,可變式分割槽分配會存在外部碎片;頁式虛擬儲存系統存在內部碎片;段式虛擬儲存系統,存在外部碎片 為了有效的利用記憶體,使記憶體產生更少的碎片,要對記憶體分頁,記憶體以頁為單位來使用,最後一頁往往裝不滿,於是形成了內部碎片。 為了共享要分段,在段的換入換出時形成外部碎片,比如5K的段換出後,有一個4k的段進來放到原來5k的地方,於是形成1k的外部碎片。
  1. 記憶體(主存)直接給CPU提供儲存,高速,低容量,價格貴,不能永久儲存資料,斷電消失,需要從輔存中重新調入資料。 
外存(輔存)給主存提供資料,低速,大容量,價格低,能永久儲存資料。
  1. 可重入碼:當被多個執行緒呼叫的時候,不會引用任何共享資料,他們是執行緒安全的。(注意與執行緒安全做區別 可重入是執行緒安全的真子集)
頁式管理有:靜態頁式管理;動態頁式管理;其中,靜態頁式管理是在作業或程序執行前,把作業或程序全部裝進記憶體中,如果記憶體中可用頁面數小於請求頁面數,該作業或程序等待。動態頁式管理不會把作業或程序一次性全部裝進記憶體,只裝入被反覆呼叫或執行的部分,其他部分在執行過程中動態裝入。
  1. 虛擬儲存器的最大容量 = min(記憶體+外存,2^n)。n為計算機的地址匯流排位數。
虛擬地址對應於物理儲存空間的大小,因而可以虛擬出看起來很大的記憶體空間,這裡虛擬地址的地址結構是:31---頁號---12---位移量w---0,這裡的地址長度正好是作業系統的記憶體位數,所以可以知道最大定址為2的32次方b,對應於kb,mb,gb的換算式如下:2^10b = 1kb2^20b = 1mb = 1kb*2^102^30b = 1gb = 1mb*2^10這裡2^32 = 2^2*1gb  = 4gb為什麼靜態重定位後的程式在記憶體中不能移動?為什麼動態重定位的程式在記憶體中可以移動?

參考答案

靜態重定位後的程式在記憶體中不能移動的原因如下:靜態重定位後的程式的程式碼發生了變化,由原來邏輯地址的程式已經變為實體地址的程式,按實體地址的方式執行,因此不能再進行移動。動態重定位的程式在記憶體中可以移動的原因如下:動態重定位是在程式執行過程中由硬體進行地址變換,變換的結果存放在記憶體地址暫存器中。程式程式碼並沒有發生變化,仍然是邏輯地址的程式碼,按邏輯地址的方式執行。因此,在記憶體中移動程式程式碼之後,僅需要根據程式碼新的起始位置,重新設定基地址暫存器的值。虛存管理與實存管理的根本區別是什麼?

參考答案

根本區別就在於,虛擬管理允許部分裝入和部分對換,而實存管理不允許這樣做。所謂"部分裝入",指的是一道應用程式不是全部裝入記憶體以後才開始執行而是隻裝入其中一部分,甚至一點都不裝入就開始執行,然後在執行的構成中根據需要逐步的裝入其餘部分;"部分對換",指的是當記憶體已滿而又有新的將"部分"需要裝入時,要把已在記憶體的某一"部分"換出去,以騰出空間存放新來者。部分裝入和部分對換的結果是可以用較小的記憶體執行較大的程式。實存管理則不同,它所要求的是整體裝入。就虛存回答以下問題: (1)虛存的應用背景是什麼? (2)虛存的可行性是什麼? (3)實現虛存的主要技術是什麼? (4)虛存可以有多大?

參考答案

(1)虛存的應用背景是用小記憶體執行大程式。這裡的"大程式"是指比整個記憶體使用者空間還要大的程式,它可以是一道程式,也可以是多道程式之和。(2)虛存的可行基礎是程式執行的區域性性原理。(3)實現虛存的主要技術是部分裝入、部分對換、區域性覆蓋、動態重定位。(4)從原理上講,虛存空間就是CPU邏輯地址所給出的空間。例如,邏輯地址是25位,則虛存空間就是225=32MB;但實際的虛擬儲存器的容量還要受輔存和記憶體空間之和的限制,實際的虛存容量不能超過這兩個物理空間之和。怎樣對記憶體進行分割槽?

參考答案

對記憶體空間的劃分是可以靜態的,也可以動態的;可以是等長的,也可以不等長。靜態劃分是指系統執行之前就將記憶體空間劃分成若干區域,通常,分配給程序的記憶體可能比程序實際所需的區域長。動態劃分是在系統執行過程中才劃分記憶體空間。這樣,系統可按程序所需要的儲存空間大小為其分配恰好滿足要求的一個或多個區域。等長分割槽是將儲存空間劃分為若干個長度相同的區域。不等長分割槽則是將儲存空間劃分若干個長度不同的區域。
  1. 記憶體洩漏
A,記憶體洩露是程式設計的bug,不是作業系統的問題B,記憶體洩露跟執行緒數無關C,記憶體洩露是程序申請了記憶體卻沒有釋放。導致佔用記憶體無限上升D,程序退出之前釋放申請的記憶體,不代表程序執行過程中沒有記憶體洩露E,java是自動管理記憶體的,但是也會有記憶體洩露,比如加入HashMap的物件hash值改變了就無法從HashMap中remove,這就造成了記憶體洩露