




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第5章 存儲管理5.1存儲管理概述5.2存儲管理方案5.3虛擬存儲管理5.4Linux的存儲管理
5.1 存儲管理概述
5.1.1 內(nèi)存的分配與回收內(nèi)存分配是為進(jìn)入系統(tǒng)準(zhǔn)備運(yùn)行的進(jìn)程分配內(nèi)存空間,內(nèi)存回收是當(dāng)進(jìn)程運(yùn)行結(jié)束后回收其所占用的內(nèi)存空間。
存儲分配方案主要包括以下要素:
(1)存儲空間的描述結(jié)構(gòu):系統(tǒng)需采用某種數(shù)據(jù)結(jié)構(gòu)來登記當(dāng)前內(nèi)存使用情況以及空閑區(qū)的分布情況,供存儲分配時使用。
(2)存儲分配的策略:系統(tǒng)需確定內(nèi)存分配和回收的算法。
5.1.2 存儲地址的變換
程序代碼中使用的地址是邏輯地址。而當(dāng)程序進(jìn)入內(nèi)存后,必須把程序中的邏輯地址轉(zhuǎn)換為程序所在的實(shí)際內(nèi)存地址。這一轉(zhuǎn)換過程稱為存儲地址的變換,或稱為地址映射。存儲地址的變換是由內(nèi)存管理模塊與硬件的地址變換機(jī)構(gòu)共同完成的。
1. 地址的概念
1)符號地址
在用高級語言編寫的源程序中,編程者使用符號名來表示操作對象或控制轉(zhuǎn)移的地址。
例5.1以下是一個C源程序的片段,其中包含了幾個符號地址。
2)邏輯地址
編譯程序?qū)⒃创a中的語句逐條翻譯為機(jī)器指令,為每個變量分配存儲單元,并用存儲單元的地址替換變量名。編譯生成的指令和數(shù)據(jù)順序存放在一起,從0開始編排地址,形成目標(biāo)代碼。目標(biāo)代碼所占有的地址范圍稱為邏輯地址空間,范圍是0~n-1,n為目標(biāo)代碼的長度。邏輯地址空間中的地址稱為邏輯地址,或相對地址。指令中引用的操作數(shù)地址或跳轉(zhuǎn)地址都是邏輯地址。
例5.2對例5.1的源程序進(jìn)行編譯,生成的目標(biāo)代碼的反匯編結(jié)果如下:
3)物理地址
物理內(nèi)存由一系列的內(nèi)存單元組成,這些存儲單元從0開始按字節(jié)編址,稱為內(nèi)存地址。當(dāng)目標(biāo)程序加載到內(nèi)存中時,它所占據(jù)的實(shí)際內(nèi)存空間就是它的物理存儲空間,物理空間中的地址稱為物理地址,或稱為絕對地址、實(shí)際地址。
序加載時所獲得的實(shí)際地址空間取決于系統(tǒng)當(dāng)時的運(yùn)行狀態(tài),因而是不確定的。假設(shè)程序分配到一段連續(xù)的內(nèi)存空間,此空間的起始地址就是它的基址,則程序中所有的邏輯地址加上此基址得到的就是物理地址。圖5-1是有關(guān)內(nèi)存地址的示意圖。圖5-1內(nèi)存地址的概念
2. 地址變換
用戶編程時使用的是邏輯地址,而CPU執(zhí)行指令時使用的是物理地址,因此必須在指令執(zhí)行前進(jìn)行地址變換,將指令中的邏輯地址轉(zhuǎn)換為CPU可直接尋址的物理地址,這樣才能保證CPU訪問到正確的存儲單元。
例5.3對例5.2的目標(biāo)代碼進(jìn)行地址變換。
地址變換的方式有兩種:
(1)靜態(tài)地址變換:程序在裝入內(nèi)存前一次性完成地址轉(zhuǎn)換。裝入內(nèi)存后的程序代碼中全部是物理地址,如例5.3所示,因而可以直接執(zhí)行。
(2)動態(tài)地址變換:程序在裝入內(nèi)存時不進(jìn)行地址變換,而是保持指令中的邏輯地址不變。在程序執(zhí)行過程中,每執(zhí)行一條指令時,如果指令中用到了邏輯地址,硬件地址變換機(jī)構(gòu)就會自動進(jìn)行地址轉(zhuǎn)換,將其變換為實(shí)際地址。
5.1.3 內(nèi)存的保護(hù)
內(nèi)存保護(hù)的含義是要確保每個進(jìn)程都在自己的地址空間中運(yùn)行,互不干擾,尤其是不允許用戶進(jìn)程訪問操作系統(tǒng)的存儲區(qū)域。對于允許多個進(jìn)程共享的內(nèi)存區(qū)域,每個進(jìn)程也只能按自己的權(quán)限(只讀、讀寫或執(zhí)行)進(jìn)行訪問,不允許超越權(quán)限進(jìn)行訪問。
常用的存儲保護(hù)措施有:
(1)界限保護(hù):在CPU中設(shè)置界限寄存器,限制進(jìn)程的活動空間。
(2)保護(hù)鍵:為共享內(nèi)存區(qū)設(shè)置一個讀寫保護(hù)鍵,在CPU中設(shè)置保護(hù)鍵開關(guān),表示進(jìn)程的讀寫權(quán)限。
(3)保護(hù)模式:將CPU的工作模式分為用戶態(tài)與核心態(tài)。
5.1.4 內(nèi)存的擴(kuò)充
盡管內(nèi)存容量不斷提高,但相比應(yīng)用規(guī)模的增長來說,內(nèi)存總是不夠的。
早期系統(tǒng)的內(nèi)存擴(kuò)充主要采用覆蓋(overlay)技術(shù),方法是將程序劃分為幾個模塊,主要模塊常駐內(nèi)存,其余模塊駐留在外存,通過交替覆蓋來共享一個或幾個存儲空間。這種覆蓋是由用戶(即編程者)有意識地進(jìn)行的。
現(xiàn)代系統(tǒng)采用虛擬存儲(virtualmemory)技術(shù)來擴(kuò)充內(nèi)存。
5.2 存儲管理方案
5.2.1 段式存儲管理按模塊化程序設(shè)計準(zhǔn)則,一個應(yīng)用程序通常劃分為一個主模塊、若干個子模塊和數(shù)據(jù)模塊等。劃分模塊的好處是可以分別編寫和編譯源程序,并且可以實(shí)現(xiàn)代碼共享、動態(tài)鏈接等編程技術(shù)。段式存儲分配就是為了適應(yīng)這種程序結(jié)構(gòu)而設(shè)計的存儲管理方案。
1. 段的概念
在段式存儲系統(tǒng)中,程序的地址空間由若干個大小不等的段組成。段(segment)是邏輯上完整的信息單位,由編程者劃分。劃分段的依據(jù)是信息的邏輯完整性以及共享和保護(hù)等需要。
分段程序中的各段從0開始編號,稱為段號。段內(nèi)從0開始編址,稱為段內(nèi)地址。因此,分段程序的邏輯地址空間是一個二維空間,其邏輯地址由段號和段內(nèi)位移兩部分組成。
2. 段式分配思想
段式分配策略是以段為單位分配內(nèi)存,每個段分配一個連續(xù)的分區(qū)。段與段間可以不相鄰接,用段表描述進(jìn)程的各段在內(nèi)存中的存儲位置。段表中包括了段長和段起始地址等信息。圖5-2描述了段式存儲的分配方式和段表的結(jié)構(gòu)。圖5-2段式分配示意圖
3. 段的分配與釋放
段式分配的方法是:系統(tǒng)用表格記錄已分配分區(qū)和空閑分區(qū)的分布和使用情況。
4. 段式地址變換
段式系統(tǒng)通過段表進(jìn)行動態(tài)地址變換。
當(dāng)CPU執(zhí)行到一條訪問內(nèi)存的指令時,指令中的邏輯地址被裝入邏輯地址寄存器,分段機(jī)構(gòu)硬件會自動地進(jìn)行地址轉(zhuǎn)換,形成實(shí)際的內(nèi)存地址。地址轉(zhuǎn)換的過程是:通過段表寄存器找到段表,以邏輯地址中的段號為索引去檢索段表,得到該段在內(nèi)存的起始地址,將其與邏輯地址中的段內(nèi)位移相加就得到了實(shí)際內(nèi)存地址。圖5-3描述了這一地址變換過程。圖5-3段式地址變換過程
5. 段式存儲的共享、保護(hù)與擴(kuò)充
段式存儲就是以段為單位的存儲共享。段的共享就是內(nèi)存中只保留該段的一個副本,供多個進(jìn)程使用。當(dāng)進(jìn)程需要共享內(nèi)存中的某段程序或數(shù)據(jù)時,只要在進(jìn)程的段表中填入共享段的信息,并設(shè)置適當(dāng)?shù)淖x寫控制權(quán),就可以訪問該段了。
段式存儲的保護(hù)方式主要是界限保護(hù)。
段式存儲空間的擴(kuò)充采用段式虛擬存儲器技術(shù),其原理是讓那些暫時用不到的段駐留在外存中,并在段表中做標(biāo)記。
6. 段式存儲管理的特點(diǎn)與問題
段式管理的特點(diǎn)是便于程序模塊化處理,可以充分實(shí)現(xiàn)分段共享和保護(hù)。但由于段需要連續(xù)存儲,因此可能出現(xiàn)“碎片”(fragment)問題。內(nèi)存碎片是指分布在內(nèi)存中的不相鄰的小塊空閑區(qū)域。隨著進(jìn)程不斷地進(jìn)入和退出系統(tǒng),存儲管理不斷地分配和回收空閑空間,一段時間后,內(nèi)存中的空閑空間就會變得支離破碎。這些碎片總和可能足夠大,但因?yàn)閱蝹€尺寸容不下一個段,不能被利用,因而降低了存儲空間的利用率。
5.2.2 頁式存儲管理
1. 分頁的概念
將進(jìn)程的邏輯地址空間分成若干大小相等的片段,稱為頁面(page),用0,1,2,…序號表示;同時,把內(nèi)存空間也按同樣大小分為若干區(qū)域,稱為頁幀(pageframe),也用0,1,2,…序號表示。
經(jīng)過分頁后,進(jìn)程使用的邏輯地址可看成由兩部分組成,即頁號和頁內(nèi)位移。x86體系結(jié)構(gòu)的邏輯地址為32位,x64體系結(jié)構(gòu)的邏輯地址為48位。若頁面大小為4?KB,則邏輯地址的低12位為頁內(nèi)位移,余下的高位為頁號,如圖5-4所示。圖5-4頁式存儲的邏輯地址結(jié)構(gòu)
應(yīng)當(dāng)注意分頁與分段概念的不同。兩者的區(qū)別在于:段是信息的邏輯單位,長度不固定,由用戶進(jìn)行劃分;頁是信息的物理單位,長度固定,由系統(tǒng)進(jìn)行劃分,用戶不可見。另外,頁式的地址空間是一維的,段式的地址空間是二維的。
2. 頁式分配思想
頁式分配的思想是以頁為單位為進(jìn)程分配內(nèi)存,每個頁幀裝一頁。一個進(jìn)程的邏輯地址空間的各個頁面可分散存放在不相鄰的頁幀中,用頁表記錄頁號與頁幀號之間的映射關(guān)系。圖5-5描述了這種分配方式和頁表結(jié)構(gòu)。圖5-5頁式分配示意圖
3. 頁面的分配與釋放
系統(tǒng)設(shè)有一個內(nèi)存分配表,記錄系統(tǒng)內(nèi)所有頁幀的分配和使用狀況。內(nèi)存分配表可采用位圖的方式或空閑鏈表方式表示。位圖是用一系列的二進(jìn)制位來描述各個頁幀的狀態(tài),每個位對應(yīng)一個頁幀,0表示空閑,1表示占用??臻e鏈表是用拉鏈的方式來組織空閑頁幀。系統(tǒng)根據(jù)內(nèi)存分配表進(jìn)行存儲分配和釋放,每次分配和釋放操作后都要相應(yīng)地修改此表。
4. 頁式地址變換
頁式系統(tǒng)通過頁表進(jìn)行動態(tài)地址變換。
當(dāng)CPU執(zhí)行到一條訪問內(nèi)存的指令時,指令中的邏輯地址被裝入邏輯地址寄存器,分頁地址變換機(jī)構(gòu)會自動地進(jìn)行地址轉(zhuǎn)換,形成實(shí)際的內(nèi)存地址。地址轉(zhuǎn)換的過程是:將邏輯地址按位分成頁號和頁內(nèi)位移兩部分,再以頁號為索引去檢索頁表,得到該頁號對應(yīng)的頁幀號。將頁內(nèi)位移與頁幀號拼接即得到實(shí)際內(nèi)存地址。圖5-6描述了這一地址變換過程。圖5-6頁式地址變換過程
5. 頁式存儲的保護(hù)與擴(kuò)充
頁式存儲的地址保護(hù)措施是對訪問地址的頁號進(jìn)行控制。在地址變換前,硬件將頁號與頁表長度進(jìn)行比較,如果沒有超出頁表長度,則進(jìn)行轉(zhuǎn)換,否則產(chǎn)生地址越界中斷信號。對共享頁面的操作是通過訪問權(quán)限來限制的。方法是在頁表中增加一個讀寫權(quán)限字段,只有當(dāng)對該頁的訪問操作與此權(quán)限的設(shè)置相匹配時方可訪問,否則產(chǎn)生讀寫保護(hù)中斷。
6. 頁式存儲管理的特點(diǎn)
頁式存儲管理是目前大部分系統(tǒng)所采用的內(nèi)存管理方案。頁式管理的優(yōu)點(diǎn)是解決了內(nèi)存碎片問題,有效地利用了內(nèi)存,使存儲空間的利用率大大地提高。不過頁式管理也有“頁內(nèi)碎片”問題,即進(jìn)程地址空間的最后一頁不一定正好放滿,空余的部分成為了碎片。不過頁內(nèi)碎片平均為每個進(jìn)程半頁,約2?KB,這個數(shù)目是可以接受的。
5.3 虛擬存儲管理
5.3.1 虛擬存儲技術(shù)1. 程序的局部性原理實(shí)驗(yàn)證明,在進(jìn)程的執(zhí)行過程中,CPU不是隨機(jī)地訪問整個程序或數(shù)據(jù)范圍,而是在一個時間段中只集中地訪問程序或數(shù)據(jù)的某一部分。進(jìn)程的這種訪問特性稱為局部性(locality)原理。局部性原理表明,在進(jìn)程運(yùn)行的每個較短的時間段中,進(jìn)程的地址空間中只有部分空間是活動的,即被CPU訪問的,其余的空間則處于不活動的狀態(tài)。
2. 虛擬存儲器原理
虛擬存儲器的原理是用外存模擬內(nèi)存,實(shí)現(xiàn)內(nèi)存空間的擴(kuò)充。做法是:在外存開辟一個存儲空間,稱為交換區(qū)。進(jìn)程啟動時,只有部分程序代碼進(jìn)入內(nèi)存,其余駐留在外存交換區(qū)中,在需要時調(diào)入內(nèi)存。內(nèi)存與交換區(qū)之間的換入換出操作由系統(tǒng)自動地進(jìn)行,應(yīng)用程序并不察覺。此時應(yīng)用程序所使用的邏輯地址空間是一個虛擬空間,其大小不受物理內(nèi)存的限制。這不僅大大方便了程序的編制,也提升了內(nèi)存的利用率。
3. 虛擬存儲器的實(shí)現(xiàn)技術(shù)
實(shí)現(xiàn)虛擬存儲器的技術(shù)要點(diǎn)是在原有的段式存儲或頁式存儲的基礎(chǔ)上增加交換功能。段式存儲加上段交換可以實(shí)現(xiàn)段式虛存。但由于段的不規(guī)則性,段交換實(shí)現(xiàn)起來比較麻煩,性能也難以保證。所以目前普遍采用的都是頁式虛存,即頁式存儲加頁面交換。
5.3.2 頁式虛擬存儲器原理
頁式虛擬存儲器的思想就是在頁式存儲管理的基礎(chǔ)上加入以頁為單位的內(nèi)外存空間的交換來實(shí)現(xiàn)存儲空間擴(kuò)充功能。這種存儲管理方案稱為請求頁式存儲。
1. 請求頁式存儲管理
圖5-7所示是一種典型的請求頁式的頁表結(jié)構(gòu)。圖5-7請求頁式頁表
2. 地址變換過程
請求頁式的地址變換過程增加了對缺頁故障的檢測。當(dāng)要訪問的頁面對應(yīng)的頁表項(xiàng)的狀態(tài)位為N時,硬件地址變換機(jī)構(gòu)會立即產(chǎn)生一個缺頁中斷信號。CPU響應(yīng)此中斷后,暫停當(dāng)前進(jìn)程的運(yùn)行,轉(zhuǎn)去執(zhí)行中斷處理程序。缺頁中斷的處理程序負(fù)責(zé)將缺頁調(diào)入內(nèi)存,并相應(yīng)地修改進(jìn)程的頁表。待原進(jìn)程再次運(yùn)行時即可使用該頁。圖5-8示意了這個過程。圖5-8請求頁式地址變換過程舉例
3. 缺頁中斷的處理
發(fā)生缺頁中斷后,CPU暫停原進(jìn)程的運(yùn)行,轉(zhuǎn)去執(zhí)行缺頁中斷的處理程序,它的任務(wù)是將進(jìn)程請求的頁面調(diào)入內(nèi)存。圖5-9描述了缺頁中斷的處理過程。圖5-9缺頁中斷處理流程
4. 頁面淘汰算法
在缺頁中斷處理中,頁面淘汰算法對系統(tǒng)的性能影響至關(guān)重要。如果淘汰算法選擇不當(dāng),系統(tǒng)可能會產(chǎn)生“抖動”(thrashing)現(xiàn)象,即剛調(diào)出的頁很快又被訪問到,馬上又被調(diào)入。抖動的系統(tǒng)處于頻繁的頁交換狀態(tài),CPU的大量時間都花在處理缺頁中斷上,故系統(tǒng)效率大幅度降低。
常用頁面淘汰算法有以下3種:
1)先進(jìn)先出法(First-In,F(xiàn)irst-Out,F(xiàn)IFO)
FIFO算法的思想是優(yōu)先淘汰最先進(jìn)入內(nèi)存的頁面,即在內(nèi)存中駐留時間最久的頁面。
2)最近最少使用法(LeastRecentlyUsed,LRU)
LRU算法不是簡單地以頁面進(jìn)入內(nèi)存的先后順序?yàn)橐罁?jù),而是根據(jù)頁面調(diào)入內(nèi)存后的使用情況進(jìn)行決策。
3)最少使用頻率法(LeastFrequentlyUsed,LFU)
LFU算法是LRU的一個近似算法。它選擇淘汰最近時期使用頻率最少的頁面。
總的來說,請求頁式存儲管理實(shí)現(xiàn)了虛擬存儲器,因而可以容納更大或更多的進(jìn)程,提高了系統(tǒng)的整體性能。但是,空間性能的提升是以犧牲時間性能為代價的,過度擴(kuò)展有可能產(chǎn)生抖動,應(yīng)權(quán)衡考慮。一般來說,外存交換空間為實(shí)際內(nèi)存空間的1~2倍比較合適。
5.4 Linux的存儲管理
Linux的存儲管理功能是由內(nèi)核的內(nèi)存管理模塊(mm)實(shí)現(xiàn)的。它的主要功能包括維護(hù)進(jìn)程的地址空間、管理和分配物理內(nèi)存空間、實(shí)現(xiàn)虛擬內(nèi)存的頁面交換功能。
5.4.1 Linux的內(nèi)存訪問機(jī)制
1. x86/x64內(nèi)存尋址模式
x86/x64的地址分為3種,即虛擬地址、線性地址和物理地址。虛擬地址就是程序中使用的邏輯地址。由于是段式存儲模式,所以虛擬地址是二維的,用段基址和段內(nèi)位移表示。線性地址是虛擬地址經(jīng)過段式變換后得到的一維地址。物理地址是線性地址經(jīng)過頁式變換得到的實(shí)際內(nèi)存地址。
2. 段式地址變換
1)x86/x64的分段機(jī)構(gòu)
在x86/x64系統(tǒng)中,進(jìn)程的虛擬地址空間被按類劃分為若干個段,每個段由一個段描述符來描述。段描述符中記錄了該段的基址、長度和訪問權(quán)限等信息。多個段描述符連續(xù)存放就形成了段描述符表,在段式映射中起到段表的作用。由系統(tǒng)中所有段描述符構(gòu)成的表稱為全局描述符表GDT,進(jìn)程也可以在GDT之上構(gòu)建私有的局部描述符表LDT。
2)x86/x64的段式變換
段式地址變換就是將指令中的虛擬地址映射為線性地址,方法是將段基址與段內(nèi)位移相加。段式變換的過程是:根據(jù)指令類型確定其所在的段,再通過對應(yīng)的段寄存器中的值檢索段描述符表,獲得該段的段描述符;用虛擬地址作為段內(nèi)位移,對照段描述符進(jìn)行界限和權(quán)限檢查;檢查通過后,將段內(nèi)位移值與段描述符中的段基址相加,形成線性地址。
3)Linux系統(tǒng)的分段機(jī)制
Linux系統(tǒng)采用的是頁式存儲模式,并不需要段式變換。頁式存儲適合于大多數(shù)硬件平臺,但在x86/x64平臺上卻不行。為了繞過x86/x64的分段機(jī)制,Linux采用了共享0基址段的方式,使得段式變換實(shí)際上不起作用。
3. 頁式地址變換
頁式地址變換就是將線性地址變換為物理地址。這是通過頁表映射完成的。
1)物理地址與線性地址
物理地址按位劃分為兩個部分,即頁幀號和頁內(nèi)位移。
2)頁表項(xiàng)的結(jié)構(gòu)
進(jìn)程映像的每個頁面都對應(yīng)一個頁表項(xiàng)(pagetableentry)。x86的頁表項(xiàng)長度為32位,x64的頁表項(xiàng)長度為64位。
圖5-10描述了頁表項(xiàng)的結(jié)構(gòu)。圖5-10?x86/x64頁表項(xiàng)結(jié)構(gòu)
3)頁表的結(jié)構(gòu)
x86的32位線性地址可尋址的內(nèi)存空間是4?GB,也就是1?M個頁面。x64的48位線性地址可尋址的內(nèi)存空間是256?TB,頁面多達(dá)64?G個。
多級分頁的思想是:將所有頁表項(xiàng)組織成多個頁表,每個頁表大小為一頁,存放在一個頁幀中。在頁表之上再增加一個頁目錄表,大小也是占一個頁幀。頁目錄表的表項(xiàng)結(jié)構(gòu)與頁表項(xiàng)基本相同,只不過其中的頁幀號是下級頁表的頁幀號。
4)二級分頁地址變換
x86的分頁機(jī)構(gòu)采用的是二級頁表結(jié)構(gòu)。頁表項(xiàng)占4字節(jié),頁目錄表和頁表的長度都是1?K項(xiàng),可映射1?M個頁面。x86的32位線性地址被劃分為三個部分:高10位為頁目錄號,中間10位為頁表號,低12位為頁內(nèi)位移。頁目錄號和頁表號與二級頁表相對應(yīng),在地址變換時用作定位表項(xiàng)的索引。圖5-11描述了x86架構(gòu)的二級分頁地址變換機(jī)制。圖5-11?x86的二級分頁地址變換示意圖
5)四級分頁地址變換
x64的分頁機(jī)構(gòu)采用的是四級分頁結(jié)構(gòu)。頁表項(xiàng)占8字節(jié),所以頁表和頁目錄表的長度都是512項(xiàng)??梢运愠?,四級頁表最多可映射64?G個頁面,也就是256?TB的內(nèi)存空間。x64的48位線性地址分為5個部分。低12位為頁內(nèi)位移,高36位分為4段,分別作為3級頁目錄表和頁表的索引。每個索引段占9位,尋址范圍是512。
圖5-12描述了Linux的四級分頁地址變換機(jī)制。圖5-12?Linux四級分頁地址變換示意圖
Linux的四級分頁是一種通用分頁模型,而不同類型的硬件架構(gòu)采用的分頁機(jī)制是不同的,可能是二級、三級或四級。為了兼容不同的硬件平臺,Linux采用了一種簡單的結(jié)構(gòu)映射策略,將四級分頁結(jié)構(gòu)映射為硬件支持的分頁結(jié)構(gòu)。
5.4.2 進(jìn)程地址空間的管理
1. 進(jìn)程的地址空間
進(jìn)程的地址空間是進(jìn)程可以使用的全部線性地址的集合,也稱為線性地址空間或虛擬地址空間。進(jìn)程地址空間是進(jìn)程看待內(nèi)存空間的一個抽象視圖,它屏蔽了物理存儲器的實(shí)際大小和分布細(xì)節(jié),使進(jìn)程得以在一個看似連續(xù)且足夠大的存儲空間中布局進(jìn)程的映像。
為便于管理,進(jìn)程的地址空間被分為兩個部分:供內(nèi)核使用的空間稱為內(nèi)核空間,供用戶進(jìn)程使用的空間稱為用戶空間。內(nèi)核映像和內(nèi)核棧都位于內(nèi)核空間,而用戶進(jìn)程的映像和棧則存放在用戶空間。
2. 地址空間的結(jié)構(gòu)
1) 映像文件
進(jìn)程的原始映像以映像文件的形式駐留在硬盤存儲空間,映像文件就是二進(jìn)制的可執(zhí)行文件。Linux的可執(zhí)行文件為ELF格式,整個文件由若干個片段(section)組成,主要的片段是代碼段、數(shù)據(jù)段和BSS段等。
文件中的映像只是靜態(tài)的代碼數(shù)據(jù),不具備運(yùn)行時的格局,也無法直接進(jìn)入內(nèi)存運(yùn)行。文件映像需要借助地址空間所構(gòu)建的映像布局才能加載進(jìn)內(nèi)存,被進(jìn)程使用。
2)虛存區(qū)
進(jìn)程準(zhǔn)備運(yùn)行時,內(nèi)核將為其建立地址空間,并將映像鏈入地址空間中。3?GB或128?TB是用戶空間的上限,實(shí)際的進(jìn)程映像只會占用其中的部分地址。為方便空間管理和訪問控制,進(jìn)程映像的每個片段占用地址空間中的一個連續(xù)區(qū)間,大小為頁的整數(shù)倍。這些被映像占用的地址區(qū)間稱為虛存區(qū)(VirtualMemoryArea,VMA)。
根據(jù)映像類型的不同,虛存區(qū)主要分為以下幾種:
代碼區(qū)(text):用于容納程序代碼,對應(yīng)映像文件中的代碼段;
數(shù)據(jù)區(qū)(data):用于容納已初始化的全局變量,對應(yīng)映像文件中的數(shù)據(jù)段;
BSS區(qū)(bss):用于容納未初始化的全局變量,對應(yīng)映像文件中的BSS段;
堆(heap):用于動態(tài)存儲分配的區(qū);
棧(stack):用于容納局部變量、函數(shù)參數(shù)、返回地址和返回值等動態(tài)數(shù)據(jù)。
3)進(jìn)程的可用地址空間
用虛存區(qū)的概念來講,一個進(jìn)程實(shí)際使用的線性地址空間是由分布在整個地址空間中的多個虛存區(qū)組成的。用pmap命令可以查看一個進(jìn)程所擁有的所有虛存區(qū)。圖5-13是根據(jù)pmap命令的輸出結(jié)果繪制的一個32位小進(jìn)程的地址空間。為簡化示例,這個程序采用了靜態(tài)庫編譯,因此結(jié)構(gòu)構(gòu)成非常簡單。一般的程序默認(rèn)采用動態(tài)庫編譯,結(jié)構(gòu)要復(fù)雜些。圖5-13Linux進(jìn)程地址空間的結(jié)構(gòu)示意圖
3. 地址空間的映射
如前所述,由虛存區(qū)構(gòu)成的地址空間是個虛擬空間的概念,是進(jìn)程可用的地址編號的范圍,并不存在實(shí)際的存儲單元。進(jìn)程映像只是被分配使用這些虛擬地址,而不是存儲在其中。進(jìn)程映像只能存放在物理存儲空間中,如磁盤或物理內(nèi)存。
作為聯(lián)系紐帶,進(jìn)程地址空間上需要建立兩方面的映射:一是虛存地址空間到文件空間的映射,稱為文件映射;二是虛存地址空間到內(nèi)存空間的映射,稱為頁表映射。文件映射將映像從文件中映射進(jìn)虛存區(qū),頁表映射則將映像從虛存區(qū)映射到內(nèi)存。此外,頁式虛存需要在內(nèi)存與交換區(qū)之間交換頁面,因此還需要建立內(nèi)存空間到交換空間的映射,稱為交換映射。圖5-14描述了各個地址空間之間的映射方式。圖5-14進(jìn)程地址空間的映射關(guān)系示意圖
1)文件映射
進(jìn)程創(chuàng)建時需要用映像文件中相應(yīng)部分的內(nèi)容構(gòu)建虛存區(qū)。當(dāng)然映像不是被調(diào)入虛存區(qū),而是在映像文件與虛存區(qū)之間建立地址映射。建立映射后,進(jìn)程采用內(nèi)存訪問方式,通過虛存地址來訪問文件,而不是用I/O方式讀寫文件。文件映射包括普通文件映射和匿名文件映射兩種,簡稱為文件映射(file-backedmapping)和匿名映射(anonymousmapping)。
(1)文件映射:文件映射就是將虛存區(qū)的地址映射到映像文件空間的一段地址上,當(dāng)進(jìn)程訪問虛存區(qū)的地址時實(shí)際就是在訪問該段文件的內(nèi)容了。
(2)匿名映射:這是一種特殊的文件映射。匿名映射的虛存區(qū)沒有對應(yīng)任何實(shí)際的映像文件,而是隱含地映射到內(nèi)核中一個抽象的“零頁”文件。
2)頁表映射
進(jìn)入了物理內(nèi)存的映像是通過頁表來映射的。頁表映射是在虛存區(qū)的線性地址到物理內(nèi)存地址間建立的映射關(guān)系。建立了頁表映射的地址空間部分是進(jìn)程實(shí)際占有的、可直接訪問的內(nèi)存空間。進(jìn)程開始執(zhí)行時,只有很少一部分映像被裝入內(nèi)存,其余部分則是在被訪問到時才調(diào)入內(nèi)存。因此,頁表映射會隨著進(jìn)程的執(zhí)行而改變。
3)交換映射
用戶進(jìn)程的映像進(jìn)入內(nèi)存后也并非始終駐留于內(nèi)存中。頁式虛存的頁面交換操作可能會在內(nèi)存緊張時將其換出到硬盤的交換空間中,當(dāng)被訪問時再交換回內(nèi)存。交換映射是在內(nèi)存地址與交換空間地址之間的映射,映射關(guān)系由內(nèi)核確定,與用戶進(jìn)程無關(guān)。
4. 進(jìn)程地址空間的管理
管理進(jìn)程地址空間的主要數(shù)據(jù)結(jié)構(gòu)是mm_struct結(jié)構(gòu)和vm_area_struct結(jié)構(gòu),前者描述的是地址空間整體,后者描述虛存區(qū)。內(nèi)核通過這些結(jié)構(gòu)來實(shí)施對進(jìn)程地址空間的管理。
1)虛存區(qū)的描述
虛存區(qū)的描述符是vm_area_struct結(jié)構(gòu),該結(jié)構(gòu)中包含了虛存區(qū)的相關(guān)數(shù)據(jù),如區(qū)的起止地址vm_start和vm_end、訪問權(quán)限vm_page_prot、標(biāo)志vm_flags、映射的文件vm_file、文件中位置偏移量vm_pgoff等。
虛存區(qū)的描述結(jié)構(gòu)如圖5-15所示。圖5-15虛存區(qū)對象的描述
2)地址空間的描述
進(jìn)程的地址空間采用mm_struct結(jié)構(gòu)來描述。mm_struct結(jié)構(gòu)也稱為內(nèi)存描述符,其中包含了與進(jìn)程地址空間有關(guān)的全部信息,如進(jìn)程的頁全局目錄指針pgd、vma鏈表的指針mmap、vma樹的指針mm_rb等。內(nèi)存描述符是進(jìn)程與內(nèi)存的接口,它連接在進(jìn)程描述符task_struct中的mm指針上,通過它進(jìn)程即可訪問自己的地址空間。這些數(shù)據(jù)結(jié)構(gòu)的關(guān)系如圖5-16所示。圖5-16進(jìn)程地址空間的描述
3)地址空間的建立與釋放
進(jìn)程最初的地址空間是從父進(jìn)程那里繼承而來的。父進(jìn)程用fork()系統(tǒng)調(diào)用創(chuàng)建子進(jìn)程時,也將自己的地址空間完整地復(fù)制給了子進(jìn)程。因此,新建的子進(jìn)程擁有與父進(jìn)程相同內(nèi)容的mm_struct結(jié)構(gòu)、vma對象和頁全局目錄,它們所映射的自然就是父進(jìn)程的物理內(nèi)存空間。也就是說,子進(jìn)程擁有了自己的線性地址空間,但共享著父進(jìn)程的物理地址空間。當(dāng)子進(jìn)程開始運(yùn)行時,父子進(jìn)程執(zhí)行的是同一個代碼段,訪問的是同一個數(shù)據(jù)段、BSS段等,直到其中一方執(zhí)行了寫操作。
虛存區(qū)所覆蓋的地址空間是進(jìn)程可以訪問的、有效的地址空間。其余的空白地址空間是進(jìn)程不可用的,唯一的例外是棧。棧的空間會隨著進(jìn)程的執(zhí)行而動態(tài)增長。當(dāng)棧超出其所在的虛存區(qū)容量時將觸發(fā)一個頁故障,內(nèi)核處理故障時會檢查是否還有空間來增長棧。一般情況下,若棧的大小低于上限(通常是8?MB)是可以增長的。如果確實(shí)無法增長了就會產(chǎn)生“棧溢出”異常,導(dǎo)致進(jìn)程終止。除棧之外,其他任何對未映射地址區(qū)的訪問都會觸發(fā)頁故障,對這類頁故障的處理是向進(jìn)程發(fā)“段錯誤”信號SIGSEGV,使進(jìn)程終止。
4)地址空間的切換
地址空間的切換發(fā)生在進(jìn)程切換時。在4.5.3節(jié)中曾提到,當(dāng)一個進(jìn)程被進(jìn)程調(diào)度程序選中投入運(yùn)行時,首先要調(diào)用switch_mm()函數(shù)進(jìn)行地址空間的切換。切換操作是將新進(jìn)程的頁表安裝到CPU上,也就是將mm_struct中的頁全局目錄指針pgd加載到CPU的cr3寄存器中,這樣就將CPU訪問的地址空間切換到了新進(jìn)程的地址空間了。
5.4.3 內(nèi)存空間的管理
1. 頁幀的描述
內(nèi)核中描述頁幀的數(shù)據(jù)結(jié)構(gòu)是page結(jié)構(gòu),每個page結(jié)構(gòu)對應(yīng)一個頁幀,其中包含了有關(guān)于該頁幀的一些信息,主要有頁的狀態(tài)flags(如該頁是否被修改過、訪問過,是否允許換出等)、頁的引用計數(shù)_refcount(為0表示頁幀空閑)、該頁對應(yīng)的映射地址mapping以及連接lru回收鏈表的指針lru等。
2. 內(nèi)存管理區(qū)的描述
由于硬件的限制,內(nèi)核并不能一視同仁地使用所有頁幀。例如,某些老式的DMA硬件(ISA設(shè)備)只能訪問低于16?MB的內(nèi)存地址,多數(shù)DMA硬件(如PCI設(shè)備)只能訪問低于4?GB的內(nèi)存地址,32位的CPU不能直接訪問高于4?GB的內(nèi)存地址等。因此,Linux將物理內(nèi)存劃分為多個區(qū)域,分別地管理和使用,這些區(qū)域稱為管理區(qū)(zone)。
3. 頁塊和伙伴的定義
若干個連續(xù)的頁幀稱為頁塊(pageblock),頁塊中所包含的頁幀數(shù)就是頁塊的大小。為方便頁塊的拆分與合并操作,頁塊的大小都是2的冪數(shù),這個冪數(shù)被用作區(qū)分頁塊大小的級別(order)。order的級數(shù)由內(nèi)核參數(shù)MAX_ORDER確定。在x86上,MAX_ORDER為11,因此order分為0~10級。0級頁塊的大小是1個頁幀,1級的是2幀,2級的是4幀,如此類推。在x64上,MAX_ORDER的默認(rèn)值為17。
4. 空閑區(qū)的描述
Linux系統(tǒng)用空閑區(qū)鏈表的方式來記錄空閑的內(nèi)存區(qū)??臻e內(nèi)存區(qū)的大小以頁塊為單位劃分。為便于查找某個尺寸的空閑頁塊,內(nèi)核將它們按order級別分別鏈接成多個鏈表,這些鏈表的頭指針保存在一個稱為free_area[]的數(shù)組中,數(shù)組的大小為MAX_ORDER項(xiàng)。每個內(nèi)存管理區(qū)的zone結(jié)構(gòu)中都有一個free_area[]數(shù)組,通過它內(nèi)核可以掌握該區(qū)域中各種尺寸的空閑頁塊的分布情況。圖5-17所示是free_area[]數(shù)組的結(jié)構(gòu)示意圖。圖5-17空閑內(nèi)存區(qū)的描述
5. 內(nèi)存分配算法
分配算法是:在free_area[i]的鏈表中找一個空閑頁塊,將其從鏈表中刪除,然后返回首幀的地址。若沒有2i大小的空閑頁塊就在free_area[i+1]的鏈表中取出一個,一分為二,分配一個,將另一個鏈入free_area[i]的鏈表中。如果沒有2i+1大小的空閑頁塊就進(jìn)一步地分裂更大的空閑頁塊。如此繼續(xù),直到分配成功。
回收內(nèi)存的過程與分配相反,就是根據(jù)回收頁塊的大小將其鏈入到適當(dāng)?shù)目臻e鏈表中。
6. 內(nèi)存的分配機(jī)制
Linux內(nèi)核提供的最底層的內(nèi)存分配函數(shù)是alloc_pages()。該函數(shù)使用Buddy算法,每次分配2的整數(shù)冪個連續(xù)的頁幀。分配成功
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 勞務(wù)合同范例產(chǎn)假
- 合作經(jīng)營協(xié)議合同范本
- 同行搶生意合同范本
- 企業(yè)抵押合同范本
- 合同范本英文翻譯
- 博羅縣購房合同范本
- 合同范例車輛買賣
- 受市場波動采購合同范例
- 商場內(nèi)搬遷合同范本
- 電力系統(tǒng)分析模擬考試題(含參考答案)
- 施工作業(yè)申請表
- 銀行間本幣市場交易員資格考試真題模擬匯編(共586題)
- 智能制造概論-3 智能制造工藝
- (全冊完整16份)北師大版五年級下冊100道口算題大全
- 50新媒體文案的具體寫作課件
- 中國ICT人才生態(tài)白皮書
- 上海煙草集團(tuán)有限責(zé)任公司招聘考試真題及答案2022
- 衛(wèi)生管理初中級職稱大綱
- 建設(shè)工程檢測人員(地基基礎(chǔ)檢測)考試復(fù)習(xí)題庫400題(含各題型)
- 記承天寺夜游(王崧舟)
- 房地產(chǎn)開發(fā)公司建立質(zhì)量保證體系情況說明
評論
0/150
提交評論