什么是内存(二):虚拟内存
通過(guò)上一篇文章的扯淡,我們應(yīng)該已經(jīng)明白了存儲(chǔ)器的層次結(jié)構(gòu),技術(shù)細(xì)節(jié)很復(fù)雜,但是思想?yún)s不難理解,因?yàn)榫褪呛芎?jiǎn)單的緩存思想。那么本文我們開(kāi)始討論關(guān)于內(nèi)存的另一個(gè)話題.虛擬內(nèi)存。其實(shí)思想也是很容易理解的。
我不知道有多少人聽(tīng)過(guò)虛擬內(nèi)存這個(gè)概念,但是虛擬內(nèi)存是計(jì)算機(jī)系統(tǒng)最重要的概念之一,并且它成功的主要原因就是它一直在沉默的,自動(dòng)的工作,換句話說(shuō),我們這些做應(yīng)用的程序員根本不需要干涉它的工作過(guò)程,但是一個(gè)沒(méi)追求的碼農(nóng)不是好的搬磚民工,所以作為一個(gè)有理想有抱負(fù)的程序員,我們還是要去理解虛擬內(nèi)存,甚至可以這樣說(shuō),如果不理解虛擬內(nèi)存,你根本不可能理解程序的深層次運(yùn)行原理。也不可能去理解匯編器,鏈接器,加載器,共享對(duì)象,文件和進(jìn)程等概念。
上篇文章中提出了幾個(gè)讓大家思考的問(wèn)題:
- 不管什么程序,最后的直接/間接的編譯結(jié)果都是0和1,(我們直接理解為匯編)。(這點(diǎn)不知道的,歡迎閱讀我的另一篇文章關(guān)于跨平臺(tái)的一些認(rèn)識(shí)),比如這句匯編代碼:mov eax,0x123456;它的意思是將內(nèi)存0x123456處的內(nèi)容送往eax這個(gè)寄存器。各個(gè)應(yīng)用的數(shù)據(jù)共同存在內(nèi)存中的。假設(shè)有一個(gè)音樂(lè)播放器應(yīng)用的匯編代碼中,引用了0x123456這個(gè)內(nèi)存地址。但是同時(shí)運(yùn)行的應(yīng)用有很多,那其他應(yīng)用也完全有可能引用 0x123456這個(gè)地址。那為什么竟然沒(méi)起沖突和錯(cuò)誤呢?
- 進(jìn)程是計(jì)算機(jī)領(lǐng)域最重要的概念之一,什么是進(jìn)程?進(jìn)程是關(guān)于某次數(shù)據(jù)集合的一次運(yùn)行活動(dòng), 是運(yùn)行在它自己地址空間的一段自包容程序, 解釋的通俗的點(diǎn), 一個(gè)程序在運(yùn)行時(shí),我們會(huì)得到一個(gè)假象,該進(jìn)程好像是獨(dú)占地使用CPU和內(nèi)存,CPU是沒(méi)有間斷地一條接一條的執(zhí)行該程序的指令,所有的內(nèi)存空間都是供該進(jìn)程的代碼和數(shù)據(jù)分配使用的。(這點(diǎn)不嚴(yán)謹(jǐn),其實(shí)內(nèi)存還有一部分要分給內(nèi)核kernel)。說(shuō)起來(lái),這個(gè)程序就好像得到了全世界一樣。,CPU是我的,內(nèi)存也全部我的,妹子們還是我的。當(dāng)然這是假象而已。但是這些假象又是怎么做到的呢?
- 程序中都會(huì)引用庫(kù)API,比如每個(gè)C程序都要引用stdio.h庫(kù)的printf(),在程序運(yùn)行時(shí),庫(kù)代碼也要被加入到內(nèi)存,這么多程序都引用了這個(gè)庫(kù),難道我內(nèi)存中需要加很多份嗎?這自然不可能,那么庫(kù)代碼又是怎么被所有進(jìn)程共享的呢?
這些讓我們細(xì)思恐極的疑問(wèn),都將通過(guò)這篇文章來(lái)給大家解答。
物理和虛擬尋址
在訪問(wèn)者看來(lái),主存就是一個(gè)有M個(gè)字節(jié)大小的單元組成的數(shù)組,每字節(jié)都有一個(gè)唯一的物理地址(Physical Address, PA)。 它的訪問(wèn)地址和數(shù)組一樣,第一個(gè)地址為0,后面地址依次為1,2,3-----M-2, M-1;這叫做線性地址空間。這種自然的訪問(wèn)內(nèi)存的方式我們稱之為物理尋址(physical addressing)。
注意:在訪問(wèn)內(nèi)存時(shí),對(duì)于任意一個(gè)地址,(不管是第0個(gè)還是第M-1個(gè)),訪問(wèn)該地址的時(shí)間總是相同的。
在各種數(shù)據(jù)結(jié)構(gòu)中,我們都說(shuō)hash表是最快的,比紅黑樹(shù)之類的都要快,那hash表為什么最快?那是因?yàn)閔ash表內(nèi)部本質(zhì)上是使用了數(shù)組。所以還是數(shù)組最快,那數(shù)組為什么最快?這是因?yàn)槲覀冎罃?shù)組的起始地址以及某個(gè)元素的序號(hào),就可以得到該元素在內(nèi)存中的地址,而對(duì)于內(nèi)存,訪問(wèn)任意一個(gè)地址,訪問(wèn)時(shí)間總是相同的。而類似鏈表,樹(shù)等結(jié)構(gòu),卻只能靠遍歷了。(不過(guò)好的hash算法還是很難設(shè)計(jì)的,這是另外一個(gè)話題了)。
圖10:一個(gè)使用物理尋址的系統(tǒng)
上圖是一個(gè)物理尋址的示例,這是一條加載指令,它讀取從物理地址4開(kāi)始的4個(gè)字節(jié),CPU通過(guò)內(nèi)存總線,將指令和地址傳遞給主存,主存讀取從物理地址4處開(kāi)始的4個(gè)字節(jié),返回給CPU。
因?yàn)檫@篇文章主要討論 虛擬內(nèi)存,是關(guān)于L4級(jí)主存和磁盤之間的交互問(wèn)題,為行文方便,文章中有時(shí)候直接說(shuō)內(nèi)存代指主存。所以這些不要誤以為是指L1,L2之類的緩存。如果看不懂這段話啥意思,務(wù)必看看我的上一篇文章什么是內(nèi)存(一):存儲(chǔ)器層次結(jié)構(gòu),然后再來(lái)看這篇文章。
早期計(jì)算機(jī)使用物理尋址方式,但是到了現(xiàn)在的多任務(wù)計(jì)算機(jī)時(shí)代,普遍使用的是虛擬尋址(virtual addressing)。如下圖所示:
圖11:一個(gè)使用虛擬尋址的系統(tǒng)
CPU 通過(guò)一個(gè)虛擬地址(virtual address,VA)來(lái)訪問(wèn)主存,這個(gè)虛擬地址在被送到主存之前會(huì)先轉(zhuǎn)換成一個(gè)物理地址。將虛擬地址轉(zhuǎn)換成物理地址的任務(wù)叫做地址翻譯(address translation)。
地址翻譯需要 CPU 硬件和操作系統(tǒng)之間的配合。 CPU 芯片上叫做內(nèi)存管理單元(Menory Management Unit, MMU)的專用硬件,利用存放在主存中的查詢表來(lái)動(dòng)態(tài)翻譯虛擬地址,該表的內(nèi)容由操作系統(tǒng)管理。
有少數(shù)現(xiàn)代計(jì)算機(jī)系統(tǒng)依舊在使用物理尋址方式,比如DSP,嵌入式系統(tǒng),超級(jí)計(jì)算機(jī)系統(tǒng)。這些系統(tǒng)的主要任務(wù)是執(zhí)行單一任務(wù),不像通用性計(jì)算機(jī)那樣需要執(zhí)行多任務(wù)。可以想象到,物理尋址方式更快。這個(gè)道理和關(guān)于跨平臺(tái)的一些認(rèn)識(shí)文章中,理論上java比C++慢的道理是一樣的。
前面解釋完虛擬地址,那么關(guān)于文章開(kāi)頭時(shí)提的那些疑問(wèn),可能有些人心里面都有數(shù)了。因?yàn)槟切┑刂范际翘摂M地址,并非真實(shí)的物理內(nèi)存當(dāng)中的地址。基本思想已經(jīng)懂了,那么剩下的我們就更具體的討論細(xì)節(jié)。
進(jìn)程地址空間
圖12:進(jìn)程地址空間
上圖是一個(gè)64位的進(jìn)程地址空間,編譯器在編譯程序時(shí),將結(jié)果編譯成32/64位的地址空間。虛擬尋址方式簡(jiǎn)化了編譯器,鏈接器的工作。同樣也因?yàn)樘摂M內(nèi)存,每個(gè)進(jìn)程才能有很大的,一致的,私有的的地址空間。這方便了內(nèi)存管理,保護(hù)了每個(gè)進(jìn)程的地址空間不被其他進(jìn)程破壞。同時(shí)也方便了共享庫(kù)。
虛擬內(nèi)存也是一種緩存思想
虛擬內(nèi)存將主存看成是一個(gè)磁盤的高速緩存,主存中只保存活動(dòng)區(qū)域,并根據(jù)需要在磁盤和主存之間來(lái)回傳送數(shù)據(jù)。
從概念上來(lái)說(shuō),虛擬內(nèi)存被組織成為一個(gè)由存放在磁盤上的 N 個(gè)連續(xù)的字節(jié)大小的單元組成的數(shù)組,也就是字節(jié)數(shù)組。每個(gè)字節(jié)都有一個(gè)唯一的虛擬地址作為數(shù)組的索引。虛擬內(nèi)存的地址和磁盤的地址之間建立影射關(guān)系。磁盤上活動(dòng)的數(shù)組內(nèi)容被緩存在主存中。在存儲(chǔ)器層次結(jié)構(gòu)中,磁盤(較低層L5,參見(jiàn)我們上篇文章圖4)的數(shù)據(jù)被分割成塊(block),這些塊作為和主存(較高層,L4)之間的傳輸單元。主存作為虛擬內(nèi)存(或者說(shuō)磁盤)的緩存。
虛擬內(nèi)存(VM)系統(tǒng)將虛擬內(nèi)存分割成稱為大小固定的虛擬頁(yè)(Virtual Page,VP),每個(gè)虛擬頁(yè)的大小為固定字節(jié)。同樣的,物理內(nèi)存被分割為物理頁(yè)(Physical Page,PP),大小也為固定字節(jié)(物理頁(yè)也稱作頁(yè)幀,page frame)。
在任意時(shí)刻,虛擬頁(yè)面都分為三個(gè)不相交的部分:
- 未分配的(Unallocated):VM 系統(tǒng)還未分配(或者創(chuàng)建)的頁(yè),未分配的頁(yè)沒(méi)有任何數(shù)據(jù)和它們關(guān)聯(lián),因此不占用任何內(nèi)存/磁盤空間。
- 緩存的(Cached):當(dāng)前已緩存在物理內(nèi)存中的已分配頁(yè)。
- 未緩存的(UnCached):該頁(yè)已經(jīng)映射到磁盤上了,但是還沒(méi)緩存在物理內(nèi)存中。
其中未分配的VP不占用任何的實(shí)際物理空間,這點(diǎn)要理解。32位程序地址空間就有4G,至于64G的程序它的地址空間是一個(gè)非常大的天文數(shù)字(貌似是16777216T),而目前我們的電腦高配的也就2T磁盤,16G內(nèi)存。如果64位程序每個(gè)VP都映射著實(shí)際的PP。無(wú)論如何也對(duì)應(yīng)不上的。并且也完全沒(méi)必要一一映射,"圖12:進(jìn)程地址空間"中可以看到,地址空間內(nèi)有大量的空白。畢竟程序不可能實(shí)際使用那么大的地址空間。
圖13:VM使用主存來(lái)作為緩存
上圖展示了在一個(gè)有 8 個(gè)頁(yè)面的虛擬內(nèi)存中,虛擬頁(yè) 0 和 3 還沒(méi)有被分配,所以在磁盤上不存在。虛擬頁(yè) 1,4,6 被緩存在物理內(nèi)存中。虛擬頁(yè) 2,5,7 已經(jīng)被映射分配了,但是還沒(méi)有緩存在主存中。
當(dāng)然,那個(gè)圖上標(biāo)注的不對(duì),VP 部分, n-p和N-1應(yīng)該分別標(biāo)注為3和7,不過(guò)我們找不到更合適的圖了,(這種圖自己畫壓力太大了)。所以大家知道我們假設(shè)共有8個(gè)VP就好了。
頁(yè)表(page table)
系統(tǒng)必須得有辦法判定某個(gè)虛擬頁(yè)是否緩存在主存的某個(gè)地方。這具體可分為兩種情況。
- 已經(jīng)在主存中,就需要判斷出該虛擬頁(yè)存在于哪個(gè)物理頁(yè)中。
- 不在主存中,那么系統(tǒng)必須判斷虛擬頁(yè)存放在磁盤的哪個(gè)位置,并且在物理主存中選擇一個(gè)犧牲頁(yè),并將該虛擬頁(yè)從磁盤復(fù)制到 主存,替換這個(gè)犧牲頁(yè)。
這些功能由軟硬件聯(lián)合提供,包括操作系統(tǒng),CPU中的內(nèi)存管理單元(Memory Management Unit,MMU)和一個(gè)存放在物理內(nèi)存中叫頁(yè)表(page table)的數(shù)據(jù)結(jié)構(gòu),頁(yè)表將虛擬頁(yè)映射到物理頁(yè)。每次地址翻譯硬件將一個(gè)虛擬地址轉(zhuǎn)換成物理地址時(shí)都會(huì)讀取頁(yè)表。
圖14:頁(yè)表
上圖展示了一個(gè)頁(yè)表的基本結(jié)構(gòu),頁(yè)表就是一個(gè)頁(yè)表?xiàng)l目(Page Table Entry,PTE)的數(shù)組。虛擬地址的每個(gè)頁(yè)在頁(yè)表中都有一個(gè)對(duì)應(yīng)的PTE。在這里我們假設(shè)每個(gè) PTE 是由一個(gè)有效位(Valid bit)和一個(gè) n 位地址字段組成的。有效位表明了該虛擬頁(yè)當(dāng)前是否被緩存在 主存 中。
- 有效位為 1,則主存緩存了該虛擬頁(yè)。地址字段就表示主存中相應(yīng)的物理頁(yè)的起始位置。
- 有效位為 0,則地址字段的null表示這個(gè)虛擬頁(yè)還未被分配,否則該地址就指向該虛擬頁(yè)在磁盤上的起始位置。
頁(yè)命中與缺頁(yè)
我們?cè)谏掀恼率裁词莾?nèi)存(一):存儲(chǔ)器層次結(jié)構(gòu)中說(shuō)過(guò)緩存命中與不命中的問(wèn)題,都是緩存思想,在這里肯定也會(huì)存在同樣的問(wèn)題。并且磁盤與主存之間的緩存不命中代價(jià)肯定大的多。因?yàn)長(zhǎng)0-L4之間,每級(jí)緩存的速度大約相差10倍左右,但是L4主存與L5磁盤之間,它們的速度相差約十萬(wàn)倍。所以主存與磁盤之間交換的頁(yè)容量是最大的,盡可能的增加命中率。相應(yīng)的替換策略,操作系統(tǒng)也使用了更加復(fù)雜精密的算法。
在上篇文章什么是內(nèi)存(一):存儲(chǔ)器層次結(jié)構(gòu),每次替換的區(qū)域,我們用了塊(block),而這里我們卻在說(shuō)頁(yè)(page), 其實(shí)同一個(gè)意思。只是因?yàn)闅v史原因,叫法不同罷了。
當(dāng)CPU想要讀取包含在某個(gè)虛擬頁(yè)的內(nèi)容時(shí),如果該頁(yè)已經(jīng)緩存在主存中,也就是頁(yè)命中。perfect,很完美。但是如果該頁(yè)沒(méi)有緩存在主存中,則我們稱之為缺頁(yè)(page fault)
圖15:對(duì)VP3中的字的應(yīng)用會(huì)引起不命中
如上圖所示,CPU 引用了 VP3 中的內(nèi)容, VP3 并未緩存在主存中。系統(tǒng)從內(nèi)存中讀取 PTE3,得知 VP3 未被緩存,這會(huì)觸發(fā)了一個(gè)缺頁(yè)異常。缺頁(yè)異常會(huì)調(diào)用kernel的缺頁(yè)異常處理程序,該程序會(huì)選擇一個(gè)犧牲頁(yè)。如下圖所示,犧牲頁(yè)選擇了存放在 PP3 中的 VP4。
圖16:VP4被犧牲了
此時(shí)如果 VP4 的內(nèi)容被修改了,kernel會(huì)將它復(fù)制回磁盤。接下來(lái),kernel從磁盤賦值 VP3 到內(nèi)存中的 PP3并更新 PTE3。隨后返回用戶進(jìn)程。當(dāng)異常處理程序返回時(shí),它會(huì)重啟執(zhí)行導(dǎo)致缺頁(yè)的指令,當(dāng)重新執(zhí)行這條指令時(shí),因?yàn)?VP3 已經(jīng)在主存中了,此時(shí)就是頁(yè)命中了。
圖17:VP3被緩存到PP3
根據(jù)習(xí)慣性的叫法,我們?cè)诖疟P和內(nèi)存之間傳送頁(yè)的活動(dòng)叫做交換(swapping)或者頁(yè)面調(diào)度(paging)。這種交換活動(dòng),只有當(dāng)不命中發(fā)生時(shí)才會(huì)發(fā)生,(也就說(shuō),系統(tǒng)并不會(huì)將磁盤內(nèi)容預(yù)存到內(nèi)存中)。這種策略被稱之為按需頁(yè)面調(diào)度(demand paging)。
我們剛才說(shuō),缺頁(yè)錯(cuò)誤是一種異常,但是實(shí)際上,在計(jì)算機(jī)系統(tǒng)中,被0除,讀寫文件,還有上篇文章中我們所說(shuō)的中斷(interrupt),甚至包括我們代碼中寫的try catch,都是一種異常。 比如被0除是intel 的CPU規(guī)定的的第0號(hào)故障(fault)類型的異常。而讀寫文件,分別是linux規(guī)定的第0號(hào)和第1號(hào)陷阱(trap)類型的異常。多任務(wù)的上下文切換,進(jìn)程的創(chuàng)建回收等,等與系統(tǒng)中這種異常流的處理密切相關(guān)。當(dāng)然,這是另外一個(gè)話題了。我們?cè)谶@里不做累述。
虛擬內(nèi)存作為內(nèi)存管理和內(nèi)存保護(hù)的工具
理所當(dāng)然的,每個(gè)進(jìn)程都有一個(gè)獨(dú)立的頁(yè)表和一個(gè)獨(dú)立的虛擬地址空間
回到文章開(kāi)頭的問(wèn)題,比如每個(gè)C程序都要調(diào)用的 stdio這個(gè)庫(kù),不可能為每個(gè)進(jìn)程都添加一份庫(kù),內(nèi)存中只有一份stdio庫(kù)的內(nèi)容,供每個(gè)使用該庫(kù)的進(jìn)程共享。
圖18:共享頁(yè)面
如上圖所示: 第一個(gè)進(jìn)程的的頁(yè)表將 VP2 映射到 某個(gè)物理頁(yè)面。而第二個(gè)進(jìn)程同樣將它的 VP2 映射到 該物理頁(yè)面。所以該物理頁(yè)面都被兩個(gè)進(jìn)程共享了。
此時(shí),大家再看一下"圖:12 進(jìn)程地址空間",就會(huì)發(fā)現(xiàn)在地址空間當(dāng)中,"共享庫(kù)的內(nèi)存映射區(qū)域"對(duì)于每個(gè)進(jìn)程起始地址都是相同的。再想想進(jìn)程之間共享內(nèi)存的通信方式, 所以說(shuō)虛擬內(nèi)存簡(jiǎn)化了共享機(jī)制
大家知道,C語(yǔ)言中存在指針,可以直接進(jìn)行內(nèi)存操作。因?yàn)橛辛颂摂M內(nèi)存,所以我們的指針操作也不會(huì)訪問(wèn)到其他進(jìn)程的區(qū)域,但是哪怕是對(duì)于自己的地址空間,很多內(nèi)存區(qū)域也應(yīng)該是禁止訪問(wèn)的,這不僅包括kernel的區(qū)域,也包括自己的只讀代碼段。那么虛擬內(nèi)存就提供了這樣的一種內(nèi)存保護(hù)工具。
地址翻譯機(jī)制可以使用一種自然的方式來(lái)提供內(nèi)存的訪問(wèn)控制。PTE 上添加一些額外的控制位來(lái)添加權(quán)限。每次 CPU 生成一個(gè)地址時(shí),地址翻譯硬件都會(huì)讀一個(gè) PTE 。
圖19:虛擬內(nèi)存提供內(nèi)存保護(hù)
在上圖中,每個(gè) PTE 額外添加了三個(gè)控制位, SUP 位表示進(jìn)程是否必須運(yùn)行內(nèi)核模式,READ和WRITE位分別控制頁(yè)面的讀寫權(quán)限。如果有指令違反了這些控制權(quán)限,那么 CPU 會(huì)觸發(fā)一個(gè)故障,并將控制傳遞給內(nèi)核中的異常處理程序。該種異常一般稱為段錯(cuò)誤(segmentation fault)。
段 和 頁(yè)
我們明白了頁(yè),頁(yè)是操作系統(tǒng)為了管理主存方便而劃分的,對(duì)用戶不可見(jiàn)。但是思考這種情況,假設(shè)一個(gè)頁(yè)的大小是1M。但是某個(gè)程序數(shù)據(jù)加起來(lái)也就0.5M,所以在內(nèi)存和磁盤進(jìn)行頁(yè)交換明顯的浪費(fèi)內(nèi)存了。所以還一種劃分方式是分段。上面那個(gè)例子,我將該段劃分為0.5M,在內(nèi)存和磁盤之間交換,這樣就避免了浪費(fèi)。
段是信息的邏輯單元,是根據(jù)用戶需求而靈活劃分的,所以大小不固定,對(duì)用戶是可見(jiàn)的,提供的是二維地址空間。
對(duì)于段,我沒(méi)找到比較好的資料,所以也沒(méi)有理解的更清楚,網(wǎng)上的很多文章都相互抄襲。據(jù)我所了解,匯編程序員是可以直接操作段的,但是我們寫高級(jí)語(yǔ)言的程序員有相應(yīng)的API能進(jìn)行段操作嗎?所以對(duì)于段的相關(guān)知識(shí),真心不了解,也希望了解的同學(xué)可以在留言區(qū)指點(diǎn)批評(píng),或者留言相關(guān)的文章鏈接。我回頭會(huì)再補(bǔ)充這篇博客。謝謝
swap分區(qū)的作用
熟悉linux的同學(xué),應(yīng)該知道linux有一個(gè)swap分區(qū)。Swap空間的作用可簡(jiǎn)單描述為:當(dāng)系統(tǒng)的物理內(nèi)存不夠用的時(shí)候,就需要將物理內(nèi)存中的一部分空間釋放出來(lái),以供當(dāng)前運(yùn)行的程序使用。那些被釋放的空間可能來(lái)自一些很長(zhǎng)時(shí)間沒(méi)有什么操作的程序,這些被釋放的空間中的信息被臨時(shí)保存到Swap空間中,等到那些程序要運(yùn)行時(shí),再?gòu)腟wap中恢復(fù)保存的數(shù)據(jù)到內(nèi)存中。系統(tǒng)總是在物理內(nèi)存不夠時(shí),才進(jìn)行Swap交換。
你電腦打開(kāi)了一個(gè)音樂(lè)播放器,但是也沒(méi)播放歌曲,然后你幾天不關(guān)機(jī),也一直沒(méi)關(guān)閉這個(gè)音樂(lè)播放器,隨著運(yùn)行的程序越來(lái)越多,內(nèi)存快不夠用了,所以操作系統(tǒng)就選擇將這個(gè)音樂(lè)播放器的內(nèi)存狀態(tài)(包括堆棧狀態(tài)等)都寫到磁盤上的swap區(qū)進(jìn)行保存。這樣就騰出來(lái)一部分內(nèi)存供其他需要運(yùn)行的程序使用。你啥時(shí)候想聽(tīng)歌了,就找到了這個(gè)音樂(lè)播放器程序操作。此時(shí), 系統(tǒng)會(huì)從磁盤中的swap區(qū)重新讀取該音樂(lè)播放器的相關(guān)信息,送回內(nèi)存接著運(yùn)行。
在window下也有類作用的硬盤空間,屬于對(duì)用戶不可見(jiàn)的匿名磁盤空間(在C盤)。
特別注意:按照字面意思,swap交換區(qū)也可以稱為虛擬內(nèi)存
硬盤上的swap交換區(qū),其實(shí)就相當(dāng)于承擔(dān)了內(nèi)存的作用(只是速度很慢罷了)。swap交換區(qū)起到了擴(kuò)大內(nèi)存的作用。所以從某些意義上來(lái)講,swap區(qū)也可以叫做虛擬內(nèi)存,但是這個(gè)虛擬內(nèi)存是字面意思。和我們本文當(dāng)中站在計(jì)算機(jī)系統(tǒng)的角度來(lái)解釋的虛擬內(nèi)存不是一個(gè)概念。所以特別注意這一點(diǎn)。因?yàn)橛行┤死斫獾奶摂M內(nèi)存,就是swap交互區(qū)。此虛擬內(nèi)存非彼虛擬內(nèi)存,所以明白各自的概念和作用。不然和其他人討論虛擬內(nèi)存,可能出現(xiàn)驢頭不對(duì)馬嘴的情況。
linux環(huán)境下叫做swap分區(qū),window下這塊區(qū)域沒(méi)叫做swap分區(qū),就直接按照字面意思叫做"虛擬內(nèi)存"了。所以兩個(gè)含義不同的虛擬內(nèi)存,讀者一定要搞清楚了。
百度百科上對(duì)虛擬內(nèi)存的解釋非常混亂
關(guān)于虛擬內(nèi)存,看了百度百科的內(nèi)容,有些地方解釋的比較混亂,有些地方是對(duì)的,但是有些地方解釋的是關(guān)于swap分區(qū)的內(nèi)容。如果光從字面意思來(lái)看,swap交換區(qū)的確可以稱為虛擬內(nèi)存,但是此虛擬內(nèi)存非彼虛擬內(nèi)存。百度百科關(guān)于這點(diǎn)的介紹比較混亂,百度百科的內(nèi)容比較多,但是沒(méi)分清這一點(diǎn),只會(huì)越來(lái)越混亂。我又查了維基百科的內(nèi)容,該詞條內(nèi)容不長(zhǎng),但是下面這段話很重要。
注意:虛擬內(nèi)存不只是“用磁盤空間來(lái)擴(kuò)展物理內(nèi)存”的意思——這只是擴(kuò)充內(nèi)存級(jí)別以使其包含硬盤驅(qū)動(dòng)器而已。把內(nèi)存擴(kuò)展到磁盤只是使用虛擬內(nèi)存技術(shù)的一個(gè)結(jié)果,它的作用也可以通過(guò)覆蓋或者把處于不活動(dòng)狀態(tài)的程序以及它們的數(shù)據(jù)全部交換到磁盤上等方式來(lái)實(shí)現(xiàn)。對(duì)虛擬內(nèi)存的定義是基于對(duì)地址空間的重定義的,即把地址空間定義為“連續(xù)的虛擬內(nèi)存地址”,以借此“欺騙”程序,使它們以為自己正在使用一大塊的“連續(xù)”地址。
所以我認(rèn)為百度百科的解釋是混亂的,而維基百科上的應(yīng)該才是正確的。
兩篇關(guān)于內(nèi)存的文章都寫完了。因?yàn)楸救瞬攀鑼W(xué)淺,若有理解錯(cuò)誤或解釋不清楚的地方,希望各位讀者打臉批評(píng)。
作者: www.yaoxiaowen.com
博客地址: www.cnblogs.com/yaoxiaowen/
github: https://github.com/yaowen369
歡迎對(duì)于本人的博客內(nèi)容批評(píng)指點(diǎn),如果問(wèn)題,可評(píng)論或郵件(yaowen369@gmail.com)聯(lián)系
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處.謝謝
轉(zhuǎn)載于:https://www.cnblogs.com/yaoxiaowen/p/7805964.html
總結(jié)
以上是生活随笔為你收集整理的什么是内存(二):虚拟内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C语言——第六周作业
- 下一篇: Alpha 冲刺 (10/10)