概述
存儲器是計算機(jī)的重要組成部分鲫忍。雖然存儲器容量近年來在不斷擴(kuò)大舰始,但是仍不能滿足現(xiàn)代軟件的發(fā)展需要第焰,存儲器仍然是一種寶貴而緊俏的資源果录。內(nèi)存管理是操作系統(tǒng)設(shè)計中最復(fù)雜和重要的內(nèi)容之一上枕,它將直接影響到內(nèi)存的利用率以及操作系統(tǒng)的性能。內(nèi)存管理的功能包括:
1 )內(nèi)存空間的分配與回收
由操作系統(tǒng)完成主存儲器空間的分配和管理弱恒,減輕程序員負(fù)擔(dān)辨萍,提高編程效率。2 )地址轉(zhuǎn)換
在多道程序環(huán)境下返弹,程序中的邏輯地址與內(nèi)存中的物理地址不可能一致锈玉,因此存儲管理必須提供地址變換功能,把邏輯地址轉(zhuǎn)換成相應(yīng)的物理地址义起。3 )內(nèi)存空間的擴(kuò)充
利用虛擬存儲技術(shù)或自動覆蓋技術(shù)拉背,從邏輯上擴(kuò)充內(nèi)存。4 )存儲保護(hù)
保證各道作業(yè)在各自的存儲空間內(nèi)運行默终,互不干擾
在學(xué)習(xí)內(nèi)存管理之前椅棺,首先學(xué)習(xí)其相關(guān)的基本概念:
程序的裝入與鏈接
將一個用戶源程序變成一個在內(nèi)存中執(zhí)行的程序,需要經(jīng)過三個步驟:
- 首先齐蔽,由編譯程序(Compiler)將用戶源代碼編譯成一個目標(biāo)模塊(Object Module)两疚;
- 其次,由鏈接程序(Linker)將目標(biāo)模塊與其需要的庫函數(shù)鏈接在一起含滴,形成一個完整的裝入模塊(Load Module)诱渤;
- 最后,由裝入程序(Loader)將裝入模塊裝入內(nèi)存蛙吏。
1 裝入
先介紹一個無需鏈接的單個目標(biāo)程序的裝入過程源哩,該目標(biāo)模塊也就是裝入模塊。內(nèi)存的裝入模塊在裝入內(nèi)存時鸦做,有三種方式:
1 )絕對裝入方式
在編譯時励烦,如果知道程序?qū)Ⅰv留在內(nèi)存的某個位置,編譯程序?qū)a(chǎn)生絕對地址的目標(biāo)代碼泼诱。絕對裝入程序按照裝入模塊中的地址坛掠,將程序和數(shù)據(jù)裝入內(nèi)存。由于程序中的邏輯地址與實際內(nèi)存地址完全相同治筒,故不需對程序和數(shù)據(jù)的地址進(jìn)行修改屉栓。
程序中所使用的絕對地址,可在編譯或匯編時給出,也可由程序員直接賦予耸袜。而通常情況下在程序中釆用的是符號地址友多,編譯或匯編時再轉(zhuǎn)換為絕對地址。絕對裝入方式只適用于單道程序環(huán)境堤框。-
2 )可重定位裝入方式
在多道程序環(huán)境下域滥,多個目標(biāo)模塊的起始地址通常都是從0開始纵柿,程序中的其他地址都是相對于起始地址的,此時應(yīng)釆用可重定位裝入方式启绰。根據(jù)內(nèi)存的當(dāng)前情況昂儒,將裝入模塊裝入到內(nèi)存的適當(dāng)位置。裝入時對目標(biāo)程序中指令和數(shù)據(jù)的修改過程稱為重定位委可,地址變換通常是在裝入時一次完成的渊跋,所以又稱為靜態(tài)重定位。
-
3 )動態(tài)運行時裝入
動態(tài)運行時裝入着倾,也稱為動態(tài)重定位拾酝,程序在內(nèi)存中如果發(fā)生移動,就需要釆用動態(tài)的裝入方式屈呕。裝入程序在把裝入模塊裝入內(nèi)存后微宝,并不立即把裝入模塊中的相對地址轉(zhuǎn)換為絕對地址,而是把這種地址轉(zhuǎn)換推遲到程序真正要執(zhí)行時才進(jìn)行虎眨。因此,裝入內(nèi)存后的所有地址均為相對地址镶摘。這種方式需要一個重定位寄存器的支持嗽桩。
2 鏈接
源程序經(jīng)過編譯后,可得到一組目標(biāo)模塊凄敢,再利用鏈接程序?qū)⑦@組目標(biāo)模塊鏈接成裝入模塊碌冶。根據(jù)鏈接時間不同,可將鏈接分為三種方式:
1 )靜態(tài)鏈接
在程序運行之前涝缝,先將各目標(biāo)模塊及它們所需的庫函數(shù)鏈接成一個完整的可執(zhí)行程序扑庞,以后不再拆開。2 )裝入時動態(tài)鏈接
將用戶源程序編譯后所得到的一組目標(biāo)模塊拒逮,在裝入內(nèi)存時罐氨,釆用邊裝入邊鏈接的鏈接方式。
其優(yōu)點是:便于修改和更新(各目標(biāo)模塊分開存放滩援,修改和更新各模塊很方便)栅隐,便于實現(xiàn)對目標(biāo)模塊的共享(OS容易將一個模塊鏈接到幾個應(yīng)用模塊上,實現(xiàn)多個應(yīng)用模塊對該目標(biāo)模塊的共享)玩徊。3 )運行時動態(tài)鏈接
對某些目標(biāo)模塊的鏈接租悄,是在程序執(zhí)行中需要該目標(biāo)模塊時,才對它進(jìn)行的鏈接恩袱。
凡是執(zhí)行過程未被使用的目標(biāo)模塊泣棋,都不會被調(diào)入內(nèi)存和鏈接到裝入模塊上,這樣不僅加快程序的裝入過程畔塔,而且節(jié)省了大量的內(nèi)存空間潭辈。
邏輯地址空間與物理地址空間
編譯后纪吮,每個目標(biāo)模塊都是從0號單元開始編址,稱為該目標(biāo)模塊的邏輯地址(或相對地址)萎胰。邏輯地址空間是指一個源程序在編譯或者連接裝配后指令和數(shù)據(jù)所用的所有相對地址的空間碾盟。
用戶程序和程序員只需知道邏輯地址,而內(nèi)存管理的具體機(jī)制則是完全透明的技竟,它們只有系統(tǒng)編程人員才會涉及冰肴。不同進(jìn)程可以有相同的邏輯地址,不同進(jìn)程相同的邏輯地址可以映射到主存的不同位置榔组。
物理地址空間是指內(nèi)存中物理單元的集合熙尉,它是地址轉(zhuǎn)換的最終地址,進(jìn)程在運行時執(zhí)行指令和訪問數(shù)據(jù)最后都要通過物理地址從主存中存取搓扯。當(dāng)裝入程序?qū)⒖蓤?zhí)行代碼裝入內(nèi)存時检痰,必須通過地址轉(zhuǎn)換將邏輯地址轉(zhuǎn)換成物理地址,這個過程稱為地址重定位锨推。
內(nèi)存保護(hù)
內(nèi)存分配前铅歼,需要保護(hù)操作系統(tǒng)不受用戶進(jìn)程的影響,同時保護(hù)用戶進(jìn)程不受其他用戶進(jìn)程的影響换可。通過釆用重定位寄存器和界地址寄存器來實現(xiàn)這種保護(hù)椎椰。
重定位寄存器含最小的物理地址值,界地址寄存器含邏輯地址值沾鳄。每個邏輯地址值必須小于界地址寄存器慨飘;內(nèi)存管理機(jī)構(gòu)動態(tài)地將邏輯地址與界地址寄存器進(jìn)行比較,如果未發(fā)生地址越界译荞,則加上重定位寄存器的值后映射成物理地址瓤的,再送交內(nèi)存單元。
當(dāng)CPU調(diào)度程序選擇進(jìn)程執(zhí)行時吞歼,派遣程序會初始化重定位寄存器和界地址寄存器圈膏。每一個邏輯地址都需要與這兩個寄存器進(jìn)行核對,以保證操作系統(tǒng)和其他用戶程序及數(shù)據(jù)不被該進(jìn)程的運行所影響浆熔。
內(nèi)部碎片與外部碎片
“碎片的內(nèi)存”描述一個系統(tǒng)中所有不可用的空閑內(nèi)存本辐。在內(nèi)存管理中,內(nèi)部碎片是已經(jīng)被分配出去的的內(nèi)存空間大于請求所需的內(nèi)存空間医增。外部碎片是指還沒有分配出去慎皱,但是由于大小太小而無法分配給申請空間的新進(jìn)程的內(nèi)存空間空閑塊。
例如:固定分區(qū)存在內(nèi)部碎片叶骨,可變式分區(qū)分配會存在外部碎片茫多;
頁式虛擬存儲系統(tǒng)存在內(nèi)部碎片;段式虛擬存儲系統(tǒng)忽刽,存在外部碎片天揖。