非分頁(yè)內(nèi)存是虛擬內(nèi)存嗎?
非分頁(yè)內(nèi)存是虛擬內(nèi)存嗎?
非分頁(yè)內(nèi)存是虛擬內(nèi)存嗎?分頁(yè)內(nèi)存和非分頁(yè)內(nèi)存區(qū)別是什么?下面是學(xué)習(xí)啦小編給大家整理的一些相關(guān)知識(shí),希望對(duì)大家有幫助!
非分頁(yè)內(nèi)存是虛擬內(nèi)存嗎?
在寫(xiě)驅(qū)動(dòng)的時(shí)候,經(jīng)常要調(diào)用ExAllocatePoolWithTag函數(shù)分配內(nèi)存,其中第一個(gè)參數(shù)可以是如下幾個(gè):
其中,主要的兩個(gè)區(qū)別就是分頁(yè)內(nèi)存和非分頁(yè)內(nèi)存。
分頁(yè)內(nèi)存是低中斷級(jí)別的例程可以訪問(wèn)的。
而非分頁(yè)內(nèi)存則是各個(gè)中斷級(jí)別的例程都可以使用的。
區(qū)別在于:
分頁(yè)內(nèi)存是虛擬內(nèi)存,在物理上未必總是能得到。
操作系統(tǒng)實(shí)現(xiàn)虛擬內(nèi)存的主要方法就是通過(guò)分頁(yè)機(jī)制。在Win32中,物理地址空間,二維虛擬地址空間和實(shí)際內(nèi)存地址是三個(gè)不同的概念。操作系統(tǒng)通過(guò)段選擇子構(gòu)成二維虛擬地址空間,每個(gè)進(jìn)程有一個(gè)4G的地址空間,然后操作系統(tǒng)的內(nèi)存管理器件把每個(gè)進(jìn)程映射到一維物理地址空間的不同部分,但是因?yàn)槲覀儗?shí)際機(jī)器上大都沒(méi)有4G內(nèi)存,所以,實(shí)際內(nèi)存空間是物理地址空間的子集。
分頁(yè)管理器把地址空間劃分成4K大小的頁(yè)面(非Intel X86體系與之不同),當(dāng)進(jìn)程訪問(wèn)某個(gè)頁(yè)面時(shí),操作系統(tǒng)首先在Cache中查找頁(yè)面,如果該頁(yè)面不在內(nèi)存中,則產(chǎn)生一個(gè)缺頁(yè)中斷(Page Fault),進(jìn)程就會(huì)被阻塞,直至要訪問(wèn)的頁(yè)面從外存調(diào)入內(nèi)存中。
我們知道,在處理低優(yōu)先級(jí)的中斷時(shí),仍可以發(fā)生高優(yōu)先級(jí)的中斷。既然缺頁(yè)過(guò)程也是一個(gè)中斷過(guò)程,那么就產(chǎn)生一個(gè)問(wèn)題,即,缺頁(yè)中斷和其他中斷的優(yōu)先級(jí)的問(wèn)題。如果在高于缺頁(yè)中斷的中斷優(yōu)先級(jí)上再發(fā)生缺頁(yè)中斷,內(nèi)核就會(huì)崩潰。所以在DISPATCH_LEVEL級(jí)別以上,絕對(duì)不能使用分頁(yè)內(nèi)存,一旦使用分頁(yè)內(nèi)存,就有發(fā)生缺頁(yè)中斷的可能,前面說(shuō)過(guò),這樣會(huì)導(dǎo)致內(nèi)核崩潰。
另一種解釋:
雖然可以尋址4GB的內(nèi)存,而在PC里往往沒(méi)有如此多的真實(shí)物理內(nèi)存。操作系統(tǒng)和硬件(這里指的是CPU中的內(nèi)存管理單元MMU)為使用者提供了虛擬內(nèi)存的概念。Windows的所有程序(包括Ring0層和Ring3層的程序)可以操作的都是虛擬內(nèi)存。之所以稱為虛擬內(nèi)存,是因?yàn)閷?duì)它的所有操作,最終會(huì)變成一系列對(duì)真實(shí)物理內(nèi)存的操作。在CPU中有一個(gè)重要的寄存器CR0,它是32位的寄存器,其中的一個(gè)位(PG位)是負(fù)責(zé)告訴系統(tǒng)是否分頁(yè)的。Windows在啟動(dòng)前會(huì)將它的PG位置1,即允許分頁(yè)。宏P(guān)AGE_SIZE記錄分頁(yè)大小4KB,4GB的虛擬內(nèi)存會(huì)被分割成1M個(gè)分頁(yè)單元。
有一部分單元會(huì)和物理內(nèi)存對(duì)應(yīng)起來(lái),這種對(duì)應(yīng)不是一一對(duì)應(yīng),而是多對(duì)一的映射,多個(gè)虛擬內(nèi)存頁(yè)可以映射同一個(gè)物理內(nèi)存頁(yè)。還有一部分單元會(huì)被映射成磁盤(pán)上的文件,并標(biāo)記為臟的(Dirty)。0~0X7FFFFFFF范圍內(nèi)的虛擬內(nèi)存,即低于2GB的虛擬地址為用戶內(nèi)核模式地址,而0X80000000~0XFFFFFFFF范圍內(nèi)的虛擬內(nèi)存,即高2GB的虛擬內(nèi)存,為內(nèi)核模式地址。Windows的核心代碼和Windows的驅(qū)動(dòng)程序加載的位置都是在高2GB的內(nèi)核地址里,所以一般的應(yīng)用程序是不能訪問(wèn)到這些核心代碼和重要數(shù)據(jù)的。同時(shí)Windows操作系統(tǒng)在進(jìn)程切換時(shí),保持內(nèi)核模式地址是完全相同的。也就是說(shuō),所有進(jìn)程的內(nèi)核地址映射完全一致,進(jìn)程切換的時(shí)候,只改變用戶模式地址的映射。
Windows規(guī)定有些虛擬內(nèi)存頁(yè)面是可以交換到文件中的,這類內(nèi)存被稱為分頁(yè)內(nèi)存。而有些虛擬內(nèi)存永遠(yuǎn)不會(huì)交換到文件中,這些內(nèi)存被稱為非分頁(yè)內(nèi)存。當(dāng)程序的中斷請(qǐng)求級(jí)在DISPATCH_LEVEL之上(包括DISPATCH_LEVEL層),程序只能使用非分頁(yè)內(nèi)存,否則將導(dǎo)致藍(lán)屏死機(jī)。
相關(guān)拓展:
分頁(yè)內(nèi)存和非分頁(yè)內(nèi)存
首先介紹幾個(gè)術(shù)語(yǔ):
進(jìn)程上下文,就是表示進(jìn)程信息的一系列東西,包括各種變量、寄存器以及進(jìn)程的運(yùn)行的環(huán)境。這樣,當(dāng)進(jìn)程被切換后,下次再切換回來(lái)繼續(xù)執(zhí)行,能夠知道原來(lái)的狀態(tài)。
中斷上下文,就是中斷發(fā)生時(shí),原來(lái)的進(jìn)程執(zhí)行被打斷,那么就要把原來(lái)的那些變量保存下來(lái),以便中斷完成后再恢復(fù)。
Windows NT和Windows 98都是運(yùn)行在支持虛擬地址空間的計(jì)算機(jī)上,虛擬地址空間或者映射到一段真實(shí)的物理內(nèi)存,或者映射到交換文件中的頁(yè)幀。
每一個(gè)進(jìn)程有4G的虛擬地址空間空間(因?yàn)橐话銠C(jī)器是32位),這4G的空間被分為用戶模式地址空間以及用戶模式地址空間。無(wú)論何時(shí)我們需要訪問(wèn)計(jì)算機(jī)內(nèi)存,都要使用內(nèi)核模式的虛擬地址。每一個(gè)用戶模式進(jìn)程都有自己的地址上下文,記錄了進(jìn)程信息的一系列東西。當(dāng)Windows NT調(diào)度器把控制從一個(gè)進(jìn)程的當(dāng)前線程切換到另一個(gè)進(jìn)程的某個(gè)線程時(shí),與進(jìn)程相對(duì)應(yīng)的虛擬地址空間也被更換(執(zhí)行到別的進(jìn)程了,也就是跑到另外的一個(gè)4G的地址)。線程切換的一個(gè)步驟就是改變處理器當(dāng)前使用的頁(yè)表,以便它能引用新線程的進(jìn)程上下文。
虛擬內(nèi)存系統(tǒng)的特征就是能使軟件有一個(gè)比物理內(nèi)存大得多的虛擬內(nèi)存空間。為了做到這一點(diǎn),內(nèi)存管理器需要在物理內(nèi)存和磁盤(pán)文件間交換頁(yè)幀。但操作系統(tǒng)的某些部分是不能被分頁(yè)的,這些內(nèi)存用來(lái)支持內(nèi)存管理器本身。最明顯的例子就是,用于處理頁(yè)故障的代碼和數(shù)據(jù)結(jié)構(gòu)必須常駐內(nèi)存。
Windows NT把內(nèi)核模式地址空間分成分頁(yè)內(nèi)存池和非分頁(yè)內(nèi)存池。(用戶模式地址空間總是分頁(yè)的) 必須駐留的代碼和數(shù)據(jù)放在非分頁(yè)池;不必常駐的代碼和數(shù)據(jù)放在分頁(yè)池中。Windows NT為決定代碼和數(shù)據(jù)是否需要駐留非分頁(yè)池提供了一個(gè)簡(jiǎn)單規(guī)則。
非分頁(yè)內(nèi)容的空間是很小的,所以一般的東西都會(huì)放入分頁(yè)內(nèi)存中。
執(zhí)行在高于或等于DISPATCH_LEVEL級(jí)上的代碼必須存在于非分頁(yè)內(nèi)存中。