內(nèi)存管理的概念
內(nèi)存管理(Memory Management)是操作系統(tǒng)設(shè)計(jì)中最重要和最復(fù)雜的內(nèi)容之一储矩。雖然計(jì)算機(jī)硬件一直在飛速發(fā)展感耙,內(nèi)存容量也在不斷增長,但是仍然不可能將所有用戶進(jìn)程和系統(tǒng)所需要的全部程序和數(shù)據(jù)放入主存中持隧,所以操作系統(tǒng)必須將內(nèi)存空間進(jìn)行合理地劃分和有效地動(dòng)態(tài)分配即硼。操作系統(tǒng)對內(nèi)存的劃分和動(dòng)態(tài)分配,就是內(nèi)存管理的概念屡拨。
有效的內(nèi)存管理在多道程序設(shè)計(jì)中非常重要只酥,不僅方便用戶使用存儲(chǔ)器、提高內(nèi)存利用率呀狼,還可以通過虛擬技術(shù)從邏輯上擴(kuò)充存儲(chǔ)器裂允。
內(nèi)存管理的功能有:
內(nèi)存空間的分配與回收:由操作系統(tǒng)完成主存儲(chǔ)器空間的分配和管理,使程序員擺脫存儲(chǔ)分配的麻煩哥艇,提高編程效率绝编。
地址轉(zhuǎn)換:在多道程序環(huán)境下,程序中的邏輯地址與內(nèi)存中的物理地址不可能一致貌踏,因此存儲(chǔ)管理必須提供地址變換功能瓮增,把邏輯地址轉(zhuǎn)換成相應(yīng)的物理地址。
內(nèi)存空間的擴(kuò)充:利用虛擬存儲(chǔ)技術(shù)或自動(dòng)覆蓋技術(shù)哩俭,從邏輯上擴(kuò)充內(nèi)存绷跑。
存儲(chǔ)保護(hù):保證各道作業(yè)在各自的存儲(chǔ)空間內(nèi)運(yùn)行,.互不干擾凡资。
在進(jìn)行具體的內(nèi)存管理之前砸捏,需要了解進(jìn)程運(yùn)行的基本原理和要求谬运。
swap介紹
? 在詳細(xì)介紹swap之前,我們需要知道的是計(jì)算機(jī)對內(nèi)存分為物理內(nèi)存與虛擬內(nèi)存(注意虛擬內(nèi)存和虛擬地址空間的區(qū)別)垦藏。物理內(nèi)存就是計(jì)算機(jī)的實(shí)際內(nèi)存大小梆暖,由RAM芯片組成的。虛擬內(nèi)存則是虛擬出來的掂骏、使用磁盤代替內(nèi)存轰驳。虛擬內(nèi)存的出現(xiàn),讓機(jī)器內(nèi)存不夠的情況得到部分解決弟灼。當(dāng)程序運(yùn)行起來由操作系統(tǒng)做具體虛擬內(nèi)存到物理內(nèi)存的替換和加載(相應(yīng)的頁與段的虛擬內(nèi)存管理)级解。這里的虛擬內(nèi)存即所謂的swap。
? 當(dāng)用戶提交程序田绑,然后產(chǎn)生進(jìn)程勤哗,在機(jī)器上運(yùn)行。機(jī)器會(huì)判斷當(dāng)前物理內(nèi)存是否還有空閑允許進(jìn)程調(diào)入內(nèi)存運(yùn)行掩驱,如果有那么則直接調(diào)入內(nèi)存進(jìn)行運(yùn)行芒划;如果沒有,那么會(huì)根據(jù)優(yōu)先級選擇一個(gè)進(jìn)程掛起欧穴,把該進(jìn)程交換到swap中等待民逼,然后把新的進(jìn)程調(diào)入到內(nèi)存中運(yùn)行。根據(jù)這種換入和換出涮帘,實(shí)現(xiàn)了內(nèi)存的循環(huán)利用拼苍,讓用戶感覺不到內(nèi)存的限制。從這也可以看出swap扮演了一個(gè)非常重要的角色焚辅,就是暫存被換出的進(jìn)程。
? 內(nèi)存與swap之間是按照內(nèi)存頁為單位來交換數(shù)據(jù)的苟鸯,一般Linux中頁的大小設(shè)置為4kb同蜻。而內(nèi)存與磁盤則是按照塊來交換數(shù)據(jù)的。
虛擬內(nèi)存的背景(virtual memory)
內(nèi)存管理算法都是基于一個(gè)基本要求:執(zhí)行指令必須在物理內(nèi)存中早处,滿足這一要求的第一種方法是整個(gè)進(jìn)程放在內(nèi)存中湾蔓。動(dòng)態(tài)載入能幫助減輕這一限制,但是它需要程序員特別小心地做一些額外的工作砌梆。
指令必須都在物理內(nèi)存內(nèi)的這一限制默责,似乎是必須和合理的,但也是不幸的咸包,因?yàn)檫@使得程序的大小被限制在物理內(nèi)存的大小內(nèi)桃序。事實(shí)上,研究實(shí)際程序會(huì)發(fā)現(xiàn)烂瘫,許多情況下并不需要將整個(gè)程序放到內(nèi)存中媒熊。即使在需要完整程序的時(shí)候,也并不是同時(shí)需要所有的程序。
因此運(yùn)行一個(gè)部分在內(nèi)存中的程序不僅有利于系統(tǒng)芦鳍,還有利于用戶嚷往。
虛擬內(nèi)存(virtual memory)將用戶邏輯內(nèi)存和物理內(nèi)存分開。這在現(xiàn)有物理內(nèi)存有限的情況下柠衅,為程序員提供了巨大的虛擬內(nèi)存皮仁。
?
物理和虛擬尋址
計(jì)算機(jī)系統(tǒng)的主存被組織成一個(gè)有M個(gè)連續(xù)的字節(jié)大小的單元組成的數(shù)組。每字節(jié)都有一個(gè)唯一的物理地址(PA)菲宴。第一個(gè)字節(jié)的物理地址為0贷祈,接下來的字節(jié)地址為2,依次類推裙顽。給定這種簡單的結(jié)構(gòu)付燥,CPU方位內(nèi)存的最自然的方式就是使用物理地址。我們把這種方式稱為物理尋址(physical addressing)愈犹。
早期的PC使用的是物理地址键科,而且諸如數(shù)字信號(hào)處理器、嵌入式微控制器以及Cray超級計(jì)算機(jī)這樣的系統(tǒng)仍然還是繼續(xù)使用這種尋址方式漩怎。然而現(xiàn)代的處理器使用的是一種稱為虛擬尋址(virtual address)的尋址方式勋颖。
使用虛擬地址,CPU通過生成一個(gè)虛擬地址(Virtual Address勋锤,VA)來訪問主存饭玲,這個(gè)虛擬地址在被送到內(nèi)存之前先轉(zhuǎn)換成適當(dāng)?shù)奈锢淼刂贰⑦@個(gè)虛擬地址轉(zhuǎn)換成物理地址的任務(wù)叫做地址翻譯(address translation)叁执。就像異常處理一樣茄厘,地址翻譯需要CPU硬件和操作系統(tǒng)的緊密合作。CPU芯片上叫做內(nèi)存管理單元(MMU)的專有硬件谈宛,利用存放主存中的查詢表來動(dòng)態(tài)的翻譯虛擬地址次哈,該表的內(nèi)容由操作系統(tǒng)來管理。
地址空間Address spaces
地址空間是一個(gè)非負(fù)整數(shù)的有序集合{0吆录,1窑滞,2,.......}恢筝。如果地址空間中的整數(shù)是連續(xù)的哀卫,那么我們說它是一個(gè)線性的連續(xù)地址空間。在一個(gè)帶有虛擬內(nèi)存的系統(tǒng)中撬槽,CPU從一個(gè)由N個(gè)地址的地址空間中生成虛擬地址此改,這個(gè)地址空間稱為虛擬地址空間(virtual address space)。一個(gè)地址空間的大小是由表示最大地址所需要的位數(shù)來描敘的≈度幔現(xiàn)代系統(tǒng)通常支持32位或者64位虛擬地址空間带斑。
一個(gè)系統(tǒng)還有一個(gè)物理地址空間(physical address space)鼓寺,對應(yīng)于系統(tǒng)中物理內(nèi)存的M個(gè)字節(jié)。地址空間的概念是十分重要的勋磕,因?yàn)樗宄貐^(qū)分了數(shù)據(jù)對象(字節(jié))和它們地屬性(地址)妈候。一旦認(rèn)識(shí)到了這種區(qū)別,那么我們就可以將其推廣了挂滓,允許每個(gè)數(shù)據(jù)對象有多個(gè)獨(dú)立地地址空間苦银,其中每個(gè)地址都選自一個(gè)不同的地址空間。這就是虛擬內(nèi)存的基本思想赶站。主存中的每字節(jié)都有一個(gè)選自虛擬空間的虛擬地址和一個(gè)選自物理空間的物理地址幔虏。
虛擬內(nèi)存作為緩存的工具
概念上而言,虛擬內(nèi)存被組織為一個(gè)由存放在磁盤上的N個(gè)連續(xù)的字節(jié)大小的單元組成的數(shù)組贝椿。每字節(jié)都有一個(gè)唯一的虛擬地址想括,作為到數(shù)組的索引。磁盤上數(shù)組的內(nèi)容被緩存到主存中烙博。和存儲(chǔ)器層次結(jié)構(gòu)中其他緩存一樣瑟蜈,磁盤(較低層)上的數(shù)據(jù)被分割為塊,這些塊作為磁盤和主存之間的傳輸單元渣窜。VM系統(tǒng)通過將虛擬內(nèi)存分割為稱為虛擬頁(Vitrual Page)的大小固定的塊來處理這個(gè)問題铺根。每個(gè)頁面大小為P字節(jié)。類似的乔宿,物理內(nèi)存頁被分割為物理頁(Physical page,PP),大小也為P字節(jié)(物理頁面也被稱為頁幀 Page frame)位迂。
在任何時(shí)刻,虛擬頁面的集合都分為三個(gè)不相交的子集:
未分配:VM系統(tǒng)還未分配(或者創(chuàng)建)的頁详瑞。未分配的塊沒有任何數(shù)據(jù)和它們相關(guān)聯(lián)掂林,因此也就不占用任何磁盤空間。
緩存的:當(dāng)前已緩存在物理內(nèi)存中的已分配頁坝橡。
未緩存的:未緩存在物理內(nèi)存中的已分配頁泻帮。
Page fault 缺頁
當(dāng)換入進(jìn)程時(shí),調(diào)頁程序推測在該進(jìn)程再次換出之前使用到的哪些頁驳庭,僅僅把需要的頁調(diào)入內(nèi)存刑顺。從而減少交換時(shí)間和所需的物理內(nèi)存空間氯窍。
這種方案需要硬件支持區(qū)分哪些頁在內(nèi)存饲常,哪些在磁盤。采用有效/無效位來表示狼讨。當(dāng)頁表中贝淤,一個(gè)條目的該位為有效時(shí),表示該頁合法且在內(nèi)存中政供;反之播聪,可能非法朽基,也可能合法但不在內(nèi)存中。
如果進(jìn)程從不試圖訪問標(biāo)記為無效的頁离陶,那么并沒有什么影響稼虎,因此,如果推測正確且只調(diào)入所有真正需要的頁招刨,那么進(jìn)程就可如同所有頁都調(diào)入內(nèi)存一樣正常運(yùn)行霎俩。
當(dāng)進(jìn)程試圖訪問這些尚未調(diào)入內(nèi)存的頁時(shí),會(huì)引起頁錯(cuò)誤陷阱(page-fault trap)沉眶。這種情況的處理方式如下:
1)檢查進(jìn)程的內(nèi)部頁表(通常與PCB一起保存)打却。以確定該引用是的合法還是非法的地址訪問。
2)如果非法谎倔,則終止進(jìn)程柳击;如果引用有效但是尚未調(diào)入頁面,則現(xiàn)在進(jìn)行調(diào)入片习。
3)找到一個(gè)空閑幀(如捌肴,從空閑幀表中選取一個(gè))。
4)調(diào)度一個(gè)磁盤操作毯侦,以便將所需頁調(diào)入剛分配的幀
5)磁盤讀操作完成后哭靖,修改進(jìn)程的內(nèi)部表和頁表,表示該頁已在內(nèi)存中侈离。
6)重新開始因陷阱而中斷的指令试幽。
計(jì)算機(jī)存儲(chǔ)體系簡介
存儲(chǔ)器是分層次的,離CPU越近的存儲(chǔ)器卦碾,速度越快铺坞,每字節(jié)的成本越高,同時(shí)容量也因此越小洲胖。寄存器速度最快济榨,離CPU最近,成本最高绿映,所以個(gè)數(shù)容量有限擒滑,其次是高速緩存(緩存也是分級,有L1叉弦,L2等緩存)丐一,再次是主存(普通內(nèi)存),再次是本地磁盤淹冰。
寄存器的速度最快库车,可以在一個(gè)時(shí)鐘周期內(nèi)訪問,其次是高速緩存樱拴,可以在幾個(gè)時(shí)鐘周期內(nèi)訪問柠衍,普通內(nèi)存可以在幾十個(gè)或幾百個(gè)時(shí)鐘周期內(nèi)訪問洋满。
存儲(chǔ)器分級,利用的是局部性原理珍坊。我們可以以經(jīng)典的閱讀書籍為例牺勾。我在讀的書,捧在手里(寄存器)阵漏,我最近頻繁閱讀的書禽最,放在書桌上(緩存),隨時(shí)取來讀袱饭。當(dāng)然書桌上只能放有限幾本書川无。我更多的書在書架上(內(nèi)存)。如果書架上沒有的書虑乖,就去圖書館(磁盤)懦趋。我要讀的書如果手里沒有,那么去書桌上找疹味,如果書桌上沒有仅叫,去書架上找,如果書架上沒有去圖書館去找糙捺〗朐郏可以對應(yīng)寄存器沒有,則從緩存中取洪灯,緩存中沒有坎缭,則從內(nèi)存中取到緩存,如果內(nèi)存中沒有签钩,則先從磁盤讀入內(nèi)存掏呼,再讀入緩存,再讀入寄存器铅檩。
2.計(jì)算機(jī)緩存 Cache
本系列的文章重點(diǎn)介紹緩存cache憎夷。了解如何獲取cache的參數(shù),了解緩存的組織結(jié)構(gòu)昧旨。
2.1 Cache 概述
cache拾给,中譯名高速緩沖存儲(chǔ)器,其作用是為了更好的利用局部性原理兔沃,減少CPU訪問主存的次數(shù)蒋得。簡單地說,CPU正在訪問的指令和數(shù)據(jù)粘拾,其可能會(huì)被以后多次訪問到窄锅,或者是該指令和數(shù)據(jù)附近的內(nèi)存區(qū)域创千,也可能會(huì)被多次訪問缰雇。因此入偷,第一次訪問這一塊區(qū)域時(shí),將其復(fù)制到cache中械哟,以后訪問該區(qū)域的指令或者數(shù)據(jù)時(shí)疏之,就不用再從主存中取出。