欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux下的進(jìn)程地址空間詳解

 更新時(shí)間:2025年06月27日 10:06:37   作者:南猿北者  
這篇文章主要介紹了Linux下的進(jìn)程地址空間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

程序地址空間回顧

我們?cè)诔鯇W(xué)C/C++的時(shí)候,我們會(huì)經(jīng)常看見老師們畫這樣的內(nèi)存布局圖:

在這里插入圖片描述

可是這真的是內(nèi)存嗎?

如果不是它內(nèi)存,那它是什么呢?

從代碼結(jié)果推結(jié)論

在回答上面的問(wèn)題之前我們先看一段代碼:

在這里插入圖片描述

運(yùn)行結(jié)果:

在這里插入圖片描述

通過(guò)運(yùn)行結(jié)果我們可以看出,父進(jìn)程的g_val一直都是保持為10,但是子進(jìn)程的g_val卻是一直在變化!這還不是最恐怖的,最恐怖的是父子進(jìn)程的g_val是一樣的地址,那么說(shuō)明父子進(jìn)程的g_val是同一塊空間啊,那么是同一塊空間的話,子進(jìn)程去修改了g_val,父進(jìn)程再去讀取g_val應(yīng)該是子進(jìn)程修改過(guò)后的,可是父進(jìn)程似乎還是讀取的以前的值(10);

首先一塊空間是不可能保存兩份值的!父子進(jìn)程能從統(tǒng)一個(gè)變量里讀取兩份值出來(lái),那么說(shuō)明父子進(jìn)程的g_val絕對(duì)不是表示的同一塊空間,&g_val出來(lái)的地址也絕對(duì)不可能是真實(shí)的物理地址!

如果&g_val出來(lái)的是物理地址的話,那么父子進(jìn)程的g_val就表示的同一塊空間,那么從同一塊空間讀取出來(lái)的值就應(yīng)該是一樣的,但是事實(shí)卻不是這樣的! 

那么就說(shuō)明我們?cè)谡Z(yǔ)言級(jí)別上的取地址,取出來(lái)的絕對(duì)不是真實(shí)的物理地址,相對(duì)的我們把這種地址叫做虛擬地址!

引入進(jìn)程地址空間

通過(guò)上面的例子我們知道了我們?cè)谡Z(yǔ)言層面上取出來(lái)的地址絕對(duì)不是真實(shí)的物理地址,這個(gè)我們知道了,可是這與我們的進(jìn)程地址空間有什么關(guān)系?

在講解進(jìn)程地址空間之前,我們先講一個(gè)故事:

在遙遠(yuǎn)的美國(guó),有一個(gè)大富豪,這個(gè)大富豪有100億美金,同時(shí)他有4個(gè)私生子:A、B、C、D這4個(gè)私生子都不知道彼此的存在,都認(rèn)為自己是大富豪唯一的孩子:

在這里插入圖片描述

有一天呢大富豪對(duì)分別A、B、C、D單獨(dú)說(shuō):你好好干,以后我的這100億家產(chǎn)都是你的!用我們現(xiàn)在的話說(shuō),大富豪的承諾相當(dāng)于在給A、B、C、D畫餅!A、B、C、D都認(rèn)為自己擁有100億美金,因?yàn)樗麄兌颊J(rèn)為自己是大富豪的唯一繼承人!在某一天A對(duì)大富豪說(shuō):“爹,給我1000美金,我需要買個(gè)表”,大富豪說(shuō)沒(méi)問(wèn)題,大富豪就從100億美金中拿出了1000美金給了A,B這時(shí)候也想大富豪申請(qǐng)了900美金,大富豪毫不猶豫的就答應(yīng)了,但是C對(duì)大富豪說(shuō):“爹,快給我50億美金,我這出了

點(diǎn)事,需要擺一下”,大富豪說(shuō):“滾!”,大富豪無(wú)情的拒絕了C的請(qǐng)求!但是C還是認(rèn)為自己擁有100億美金,因?yàn)樗J(rèn)為自己是大富豪的唯一繼承人,等到大富豪駕鶴西去之時(shí)就是100億美金到賬之日!

在上面的故事中呢:A、B、C、D相當(dāng)于我們的進(jìn)程;

大富豪給A、B、C、D畫的“餅”就是進(jìn)程地址空間!

100億美金就是物理內(nèi)存;

大富豪就是OS;

其中A、B、C、D向大富豪借錢的動(dòng)作就是向OS申請(qǐng)物理內(nèi)存!申請(qǐng)的太多,OS是會(huì)拒絕我們的!

OS最為我們計(jì)算機(jī)中的管理者,那么它要不要把給進(jìn)程們畫的“餅”管理起來(lái)呢?

答案是要的!為什么呢?如果不管理起來(lái)的畫,在進(jìn)程多起來(lái)的時(shí)候OS也不知到他給進(jìn)程們到底畫的什么餅!

那么如何管理這些“餅”呢?

先描述,再組織

在Linux中,OS利用了一個(gè)struct mm_struct{}的結(jié)構(gòu)體將這個(gè)餅管理了起來(lái),每個(gè)進(jìn)程都有屬于自己的專屬大餅,其中進(jìn)程的pcb是中具有指向該大餅的指針!OS呢會(huì)將這些大餅做一個(gè)區(qū)域劃分!比如規(guī)定大餅的這個(gè)區(qū)域是干嘛的,那個(gè)區(qū)域是干嘛的!這些區(qū)域,也就是我們看到的什么堆區(qū)、棧區(qū)、代碼區(qū)等等!這個(gè)大餅也就是我們老師在日常中講解的C/C++內(nèi)存布局:

在這里插入圖片描述

Linux下的mm_struct 結(jié)構(gòu)體就是專門記錄這張大餅的!

struct mm_struct{
long Code_start;
long Code_end;
long init_start;
long init_end;
……
long stack_start;
long stack_end;
}

當(dāng)我們向堆區(qū)申請(qǐng)空間時(shí)heap_end就會(huì)變大,free時(shí)heap_end就會(huì)變小!

說(shuō)白了進(jìn)程地址空間就是OS欺騙進(jìn)程的一種手段,讓內(nèi)存誤以為自己擁有全部的物理內(nèi)存;

頁(yè)表

可是進(jìn)程地址空間畢竟只是邏輯上的內(nèi)存,并不是真正的物理內(nèi)存,是不能存儲(chǔ)數(shù)據(jù),進(jìn)程的數(shù)據(jù)和代碼是只能存儲(chǔ)在物理內(nèi)存上的,但是進(jìn)程使用的是虛擬內(nèi)存!進(jìn)程也只能訪問(wèn)虛擬地址,但是實(shí)際的數(shù)據(jù)是存儲(chǔ)在物理內(nèi)存上的,那么進(jìn)程是如何通過(guò)虛擬地址拿到數(shù)據(jù)和代碼的?

實(shí)際上在虛擬地址與物理地址之間是有一種映射關(guān)系的,這種映射關(guān)系被存儲(chǔ)在頁(yè)表中!每個(gè)進(jìn)程都有自己的頁(yè)表!

在這里插入圖片描述

當(dāng)進(jìn)程需要訪問(wèn)虛擬地址上某一處的數(shù)據(jù)時(shí),OS就會(huì)拿著進(jìn)程提供的虛擬地址,根據(jù)該進(jìn)程提供的頁(yè)表轉(zhuǎn)換成對(duì)于的物理地址,然后去對(duì)于的物理內(nèi)存上取數(shù)據(jù)在交給進(jìn)程!這個(gè)過(guò)程進(jìn)程是看不到的,站在進(jìn)程的角度就是,我(進(jìn)程)需要訪問(wèn)虛擬地址為0x11223344處的數(shù)據(jù),然后就直接拿到了數(shù)據(jù),在進(jìn)程看來(lái)它就認(rèn)為自己的數(shù)據(jù)是存儲(chǔ)在虛擬內(nèi)存上的,只要自己需要,隨時(shí)都可以拿到,殊不知其真實(shí)數(shù)據(jù)是存儲(chǔ)在物理內(nèi)存上的,進(jìn)程之所以能隨時(shí)拿到數(shù)據(jù),都是由OS完成的!我們來(lái)畫個(gè)圖來(lái)理解:

在這里插入圖片描述

只要理解了這一層,我們就能回答開頭的問(wèn)題了:

老師們經(jīng)常給我們講的內(nèi)存分布實(shí)際上并不是真實(shí)(物理內(nèi)存)的內(nèi)存的分布,而是OS給進(jìn)程畫的一張“大餅”,就是讓進(jìn)程認(rèn)為自己一個(gè)就擁有整個(gè)內(nèi)存!說(shuō)白了進(jìn)程空間就是OS欺騙進(jìn)程的一種手段!

每個(gè)進(jìn)程都有屬于自己的一張進(jìn)程地址空間和對(duì)應(yīng)的頁(yè)表!

回答了開頭的問(wèn)題,我們?cè)賮?lái)解釋一下,上面代碼表現(xiàn)出的情況,父子進(jìn)程對(duì)于g_val取地址取出的地址是一樣的,但是父子進(jìn)程從g_val取出來(lái)的值卻不一樣:

首先父進(jìn)程會(huì)有自己的pcb、進(jìn)程空間地址、頁(yè)表,那么子進(jìn)程也會(huì)擁有這些東西,但是子進(jìn)程作為父進(jìn)程的兒子,它會(huì)繼承父進(jìn)程的大部分屬性,包括進(jìn)程空間地址、頁(yè)表等,畫圖表示就是:

在這里插入圖片描述

那么根據(jù)上面圖的表示的話,父子進(jìn)程的g_val不就是同一塊空間嘛,取出來(lái)的值也應(yīng)該是一樣的,可是為什么父子進(jìn)程g_val取出來(lái)不同的值?

我們需要記得進(jìn)程之間是具有獨(dú)立性的!包括父子進(jìn)程之間也是如此!當(dāng)我們的子進(jìn)程在嘗試對(duì)g_val變量的值進(jìn)行修改時(shí),為了不影響父進(jìn)程的正常讀取g_val,OS會(huì)啟動(dòng)"寫時(shí)拷貝"技術(shù),當(dāng)父子進(jìn)程中的某個(gè)進(jìn)程需要對(duì)父子進(jìn)程共享的同一塊空間

進(jìn)行修改時(shí),OS會(huì)在物理內(nèi)存重新開辟一塊一摸一樣大的空間,然后再將數(shù)據(jù)拷貝過(guò)來(lái),修改需要修改數(shù)據(jù)的進(jìn)程的頁(yè)表映射關(guān)系!此時(shí)需要修改數(shù)據(jù)的進(jìn)程就可以隨意的修改了,同時(shí)不會(huì)影響另一個(gè)進(jìn)程的數(shù)據(jù)!保持了進(jìn)程之間的獨(dú)立性;

畫個(gè)圖來(lái)表示:

在這里插入圖片描述

這也就解釋了為什么父子進(jìn)程的g_val是同一個(gè)地址,但是卻存著不同的值!

地址相同的原因就是:g_val都處于父子進(jìn)程的進(jìn)程地址空間的同一個(gè)位置(這里說(shuō)的“處于”并不是真實(shí)的存儲(chǔ),而是邏輯上的存儲(chǔ)!),取地址取出來(lái)的地址當(dāng)然一樣,但是由于子進(jìn)程的g_val++造成了寫實(shí)拷貝,就導(dǎo)致了父子進(jìn)程的g_val映射到不

同的物理地址空間,取出來(lái)的值自然不一樣!

寫時(shí)拷貝是發(fā)生在物理內(nèi)存,對(duì)于虛擬內(nèi)存沒(méi)有影響! 

注意:我們平時(shí)&地址,取出來(lái)的全是虛擬地址(也就是進(jìn)程地址空間中的地址),我們用戶沒(méi)辦法取到真實(shí)的物理地址,畢竟誰(shuí)叫我們的進(jìn)程被OS欺騙了,癡癡的認(rèn)為自己享有全部?jī)?nèi)存!

明白了上面的例子,那么我們也就能很好的明白了使用fork函數(shù)時(shí),利用變量接受fork返回值時(shí),明明是同一個(gè)變量(虛擬地址相同),但是再父子進(jìn)程中卻輸出了不同的值;

主要是應(yīng)為再fork函數(shù)的內(nèi)部也就是return的前一步的時(shí)候,子進(jìn)程就已經(jīng)被創(chuàng)建出來(lái)了,此時(shí)對(duì)于接受fork返回值的變量在父子進(jìn)程中也還是映射的同一塊物理空間,但是當(dāng)return的時(shí)候,就會(huì)向這個(gè)接受返回值的變量中寫入數(shù)據(jù),此時(shí)就會(huì)觸發(fā)寫時(shí)拷貝,那么這時(shí)候父子進(jìn)程中的某個(gè)進(jìn)程就會(huì)為自己的這個(gè)接受fork返回值的變量重新映射一塊新的物理空間!這也就是fork函數(shù)能返回兩個(gè)返回值的秘密!實(shí)際上并不是真的能返回兩個(gè)返回值,只是父子進(jìn)程中的接受返回值的變量已經(jīng)是兩塊獨(dú)立的物理空間了,不在是同一塊!在虛擬內(nèi)存上他們也許是同一塊,但是,真實(shí)情況并不是!!! 

同時(shí)頁(yè)表也不止是會(huì)映射虛擬地址的物理地址,頁(yè)表同時(shí)也會(huì)記錄一下映射的物理地址的讀寫權(quán)限!

比如:

在這里插入圖片描述

這也是為什么我們平常所說(shuō)的代碼區(qū)的數(shù)據(jù)只能讀!不可修改的原因!

因?yàn)楫?dāng)我們進(jìn)程試圖修改代碼區(qū)的數(shù)據(jù)時(shí),OS會(huì)拿著進(jìn)程提供的虛擬地址(代碼區(qū)的地址),然后根據(jù)頁(yè)表映射到對(duì)應(yīng)的物理內(nèi)存上去,但是OS這時(shí)候發(fā)現(xiàn)這次映射的物理空間在頁(yè)表中的權(quán)限也就只有可讀,不可修改!我們的操作屬于權(quán)限放大了,

OS會(huì)直接拒絕我們的請(qǐng)求!并不是這塊空間(物理內(nèi)存)本身就只是可讀的!而是我們通過(guò)一些手段從邏輯上限制了這塊空間(物理內(nèi)存)的權(quán)限!

為什么要有進(jìn)程地址空間

上面我們大概講解了什么是進(jìn)程地址空間和怎么使用進(jìn)程地址空間,但是為什么要有這個(gè)東西呢?

1、防止地址隨意訪問(wèn),保護(hù)我們進(jìn)程的安全和獨(dú)立;

假設(shè)我們不使用虛擬內(nèi)存,就直接使用物理內(nèi)存:

在這里插入圖片描述

我們現(xiàn)在在物理內(nèi)存中加載了兩個(gè)程序,現(xiàn)在A程序是我們寫的,但是我們的代碼能力有問(wèn)題,我們的A程序有bug,當(dāng)我們cpu在處理進(jìn)程A的時(shí)候,會(huì)從進(jìn)程中讀取到不屬于進(jìn)程A的地址,也就是說(shuō)A進(jìn)程存在野指針問(wèn)題,但是剛好這個(gè)野指針被OS分配給了進(jìn)程B使用;

要是這時(shí)候我們的進(jìn)程A有個(gè)對(duì)該野指針解引用并修改數(shù)據(jù)的操作的話,那就完了因?yàn)檫@就造成了我們明明實(shí)在運(yùn)行進(jìn)程A但是由于野指針的問(wèn)題間接的將B進(jìn)程的數(shù)據(jù)修改了,如果進(jìn)程B是個(gè)銀行的賬戶信息的話,那么后果就會(huì)很嚴(yán)重!這也就破壞了進(jìn)程之間的獨(dú)立性?。⊥瑫r(shí)也對(duì)進(jìn)程的安全運(yùn)行造成了威脅!但是我們使用虛擬內(nèi)存時(shí),我們?nèi)绻斐闪嗽浇缭L問(wèn),OS會(huì)在映射該虛擬地址的時(shí)候檢測(cè)出來(lái),從而拒絕我們的訪問(wèn)!這也就讓我們無(wú)法隨意的根據(jù)地址訪問(wèn)其他空間了,同時(shí)進(jìn)程的獨(dú)立性和安全性也就增加了!

2、進(jìn)程管理與內(nèi)存管理解耦合了;

再此之前我們先來(lái)談?wù)刴alloc的本質(zhì)!

請(qǐng)問(wèn)只要是我們已使用malloc或new申請(qǐng)空間OS就會(huì)立即給我們嗎?

答案:顯然不是!OS作為整個(gè)計(jì)算機(jī)最基礎(chǔ)的軟件,也是整個(gè)計(jì)算機(jī)中的管理者!它是不允許發(fā)生任何不高效和浪費(fèi)的操作的!

如果有,那么一定是OS的bug;

如果OS在我們申請(qǐng)的時(shí)候就把空間給我們了,那么我們能保證我們申請(qǐng)了就一定使用嗎?我們一定寫過(guò)這樣的代碼:在程序的開頭就先申請(qǐng)了一段空間,但是我們可能寫了幾十行代碼才開始使用這塊空間!那么在你從申請(qǐng)空間開始到你真正使用這塊空間之間,這塊空間就一直被我們占著,其他進(jìn)程也用不到,實(shí)屬有點(diǎn)“站著茅坑不拉屎”的感覺(jué)!你說(shuō)一個(gè)進(jìn)程這樣!OS還能理解,但是如果每個(gè)進(jìn)程都像這樣了!這就會(huì)嚴(yán)重的造成內(nèi)存資源使用不充分、不高效;

如果在我們并未真正使用這段空間的時(shí)間段內(nèi),OS將這塊空間拿去給需要的進(jìn)程使用,當(dāng)我們真正需要使用這塊空間的時(shí)候OS再給我們,這樣的話內(nèi)存使用率不就起來(lái)了!

那也有人會(huì)說(shuō),我們申請(qǐng)了立馬使用就好了嘛,對(duì)不起!在你剛好申請(qǐng)完這塊空間的時(shí)候CPU處理你的時(shí)間到了,該換下一個(gè)進(jìn)程被CPU處理了!在你等待下一次CPU處理的時(shí)候,你又是單獨(dú)站在這塊空間,自己不用其他進(jìn)程也用不了!又會(huì)造成內(nèi)存資源的浪費(fèi)!OS也不會(huì)允許!

為此在我們向OS申請(qǐng)空間的時(shí)候,OS不會(huì)立馬給我們!而是當(dāng)我們真正需要的時(shí)候才會(huì)給我們!

我們平常使用的malloc、new就是這樣的原理;malloc、new是在虛擬內(nèi)存上開辟空間(也就是邏輯上開辟的空間)返回的指針也自然是虛擬指針,雖然我們有了空間,但這些空間畢竟是邏輯上的,并不能真實(shí)的存儲(chǔ)數(shù)據(jù),也就是說(shuō)這些虛擬空間還沒(méi)有在頁(yè)表中建立起與物理內(nèi)存的映射關(guān)系,進(jìn)程現(xiàn)在拿到的只是一張空頭支票,具體的兌換,還是得靠OS!只有當(dāng)我們真正需要使用這塊空間的時(shí)候,OS才會(huì)將我們申請(qǐng)的虛擬空間映射到對(duì)應(yīng)的物理內(nèi)存!也就是為我們的虛擬空間在頁(yè)表中建立起物理地址!只有完成映射關(guān)系,我們進(jìn)程才能算是真正的擁有自己的空間(物理空間)!

同時(shí)我們進(jìn)程也不必關(guān)心,OS到底給我們映射的那塊空間,在物理內(nèi)存中是否連續(xù)等!OS可以在物理內(nèi)存的任何位置映射空間,物理內(nèi)存并不一定是連續(xù)的,但是我們?cè)谔摂M內(nèi)存上申請(qǐng)的空間一定是連續(xù)的!

我們作為進(jìn)程是不關(guān)心我們的數(shù)據(jù)到底存儲(chǔ)在物理內(nèi)存的那一塊空間的、申請(qǐng)的物理空間是否連續(xù)等等,在進(jìn)程看來(lái)進(jìn)程空間地址就是它的“內(nèi)存”,只要在進(jìn)程空間地址上連續(xù)就行了!至于映射到物理內(nèi)存上是什么情況,我們進(jìn)程壓根不關(guān)心!

為此我們把就把內(nèi)存管理與進(jìn)程管理分開了!內(nèi)存管理就處理內(nèi)存的事!進(jìn)程管理就專門管理進(jìn)程!兩個(gè)管理之間互不干擾!

在這里插入圖片描述

如果沒(méi)有進(jìn)程空間地址的話,我們的進(jìn)程在申請(qǐng)空間的時(shí)候,OS就會(huì)立馬給它,這樣導(dǎo)致內(nèi)存資源浪費(fèi)不說(shuō)!OS會(huì)需要去刻意尋找一塊物理內(nèi)存,這時(shí)候就造成進(jìn)程管理與內(nèi)存管理耦合!也就是說(shuō)我們我們?cè)谶M(jìn)行進(jìn)程管理的時(shí)候就必須借助內(nèi)存管理的力量!這是我們不希望看到的,我們希望進(jìn)程管理能夠單獨(dú)完成自己的事情,內(nèi)存管理也能單獨(dú)完成自己的事情,兩個(gè)進(jìn)程耦合度不要太高!保證我們內(nèi)存管理崩潰的時(shí)候不影響進(jìn)程管理!進(jìn)程管理崩潰的時(shí)候不影響內(nèi)存管理!

有了進(jìn)程地址空間,我們?cè)谏暾?qǐng)空間的時(shí)候就只啟用進(jìn)程管理,先申請(qǐng)?zhí)摂M內(nèi)存,當(dāng)我們真正需要的時(shí)候,再啟動(dòng)內(nèi)存管理來(lái)為我們分配物理空間!這樣的話就算內(nèi)存管理崩潰掉了也不影響進(jìn)程管理! 

3、讓進(jìn)程以統(tǒng)一的視角看待內(nèi)存;

虛擬內(nèi)存是OS欺騙進(jìn)程的一種手段,進(jìn)程在看待進(jìn)程的時(shí)候都認(rèn)為自己擁有整塊內(nèi)存,然后開始對(duì)著“這塊內(nèi)存”開始布局自己的代碼和數(shù)據(jù),但是實(shí)際上這些代碼和數(shù)據(jù)到底存沒(méi)存儲(chǔ)起來(lái),還得看OS,但是站在進(jìn)程的角度,他是認(rèn)為我們已經(jīng)布局完整個(gè)內(nèi)存了!進(jìn)程是看不到真實(shí)物理內(nèi)存的!進(jìn)程只能看到進(jìn)程地址空間! 

4、可以充分的利用內(nèi)存資源,讓內(nèi)存的利用率變的高效起來(lái)!

比如:兩個(gè)進(jìn)程可能都需要訪問(wèn)某個(gè)動(dòng)態(tài)庫(kù);如果沒(méi)有進(jìn)程地址空間的話,OS就會(huì)將這個(gè)動(dòng)態(tài)庫(kù)加載內(nèi)存兩次,也就是內(nèi)存中會(huì)有兩份一模一樣的數(shù)據(jù)!這是沒(méi)必要的!但是有了進(jìn)程地址空間過(guò)后,我們可以讓兩個(gè)進(jìn)程的虛擬地址同時(shí)映射到這同一份數(shù)據(jù)!也就是說(shuō)兩個(gè)進(jìn)程可以共享這份數(shù)據(jù)!這份數(shù)據(jù)也就只需要在內(nèi)存中存在一份就行了!但是在進(jìn)程看來(lái)他們都認(rèn)為這份數(shù)據(jù)是自己獨(dú)享的!

在這里插入圖片描述

重新理解進(jìn)程地址空間

請(qǐng)問(wèn)我們的程序在編譯完畢,但是還沒(méi)有加載進(jìn)內(nèi)存的時(shí)候,我們的程序內(nèi)部是否有地址呢?

答案是當(dāng)然有的!

我們可以來(lái)看看一段代碼的匯編文件:

在這里插入圖片描述

我們將這段程序先編譯成可執(zhí)行程序,然后利用命令objdump -S對(duì)其進(jìn)行反匯編:

在這里插入圖片描述

我們會(huì)發(fā)現(xiàn),在我們的程序在未加載進(jìn)內(nèi)存的時(shí)候,編譯器就已經(jīng)確定好了各條指令的地址!這是為什么??

答:進(jìn)程地址空間不止是欺騙進(jìn)程的,也會(huì)連同編譯器也一起欺騙!當(dāng)然這都是非常不標(biāo)準(zhǔn)的描述,嚴(yán)格意義上來(lái)說(shuō),源代碼在被編譯的時(shí)候,就已經(jīng)按照虛擬地址空間的方式對(duì)代碼和數(shù)據(jù)進(jìn)行了地址的編制,只不過(guò)只些代碼和數(shù)據(jù)的地址都是虛擬地址,并不是真實(shí)的物理地址!

只有當(dāng)我們的程序被加載進(jìn)內(nèi)存了,才會(huì)真正的擁有物理地址!

現(xiàn)在我們來(lái)理一理整個(gè)程序的運(yùn)行過(guò)程:

1、將我們的程序加載進(jìn)內(nèi)存(注意并不是一次性全部加載進(jìn)去,而是先加載一些比較重要的代碼和數(shù)據(jù));

2、OS為該程序建立pcb,來(lái)管理該進(jìn)程;

3、OS為該進(jìn)程創(chuàng)建地址空間地址和頁(yè)表;

4、cpu從特定的進(jìn)程空間地址處讀取數(shù)據(jù)!然后OS在根據(jù)cpu提供的虛擬地址,映射到對(duì)應(yīng)物理地址,獲取對(duì)應(yīng)的數(shù)據(jù)給cpu,cpu開始處理!如果OS在根據(jù)cpu提供虛擬地址沒(méi)有建立起對(duì)應(yīng)的物理地址時(shí),OS會(huì)暫停cpu對(duì)于該進(jìn)程的處理,然后重新加載一部分?jǐn)?shù)據(jù)進(jìn)入內(nèi)存,然后再建立映射關(guān)系,出現(xiàn)這種情況:叫做缺頁(yè)中斷!

我們畫個(gè)圖來(lái)理解:

在這里插入圖片描述

注意:在CPU上讀取到的地址,全是進(jìn)程空間上的地址,也就是虛擬地址!CPU也不會(huì)直接去物理內(nèi)存上讀取數(shù)據(jù)!

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 13個(gè)實(shí)用的Apache Rewrite重寫規(guī)則

    13個(gè)實(shí)用的Apache Rewrite重寫規(guī)則

    這篇文章主要介紹了13個(gè)實(shí)用的Apache Rewrite重寫規(guī)則,需要的朋友可以參考下
    2014-03-03
  • Linux五步構(gòu)建內(nèi)核樹

    Linux五步構(gòu)建內(nèi)核樹

    大家好,本篇文章主要講的是Linux五步構(gòu)建內(nèi)核樹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 詳解linux usb host驅(qū)動(dòng)編寫入門

    詳解linux usb host驅(qū)動(dòng)編寫入門

    本篇文章主要介紹了詳解linux usb host驅(qū)動(dòng)編寫入門,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • LINUX服務(wù)器安裝SVN服務(wù)實(shí)現(xiàn)方式

    LINUX服務(wù)器安裝SVN服務(wù)實(shí)現(xiàn)方式

    本文介紹了如何使用yum安裝Subversion,創(chuàng)建版本庫(kù),配置SVN服務(wù),并解決常見問(wèn)題,詳細(xì)步驟包括安裝Subversion,查看安裝版本和位置,創(chuàng)建存放版本庫(kù)的目錄及svn版本庫(kù),配置權(quán)限控制,啟動(dòng)svn版本庫(kù),以及處理端口訪問(wèn)權(quán)限等
    2024-09-09
  • 詳解Linux Socket編程(不限Linux)

    詳解Linux Socket編程(不限Linux)

    本篇文章主要介紹了Linux Socket編程,網(wǎng)絡(luò)之間的通信全靠Socket,詳細(xì)的介紹了Socket,有興趣的同學(xué)可以了解一下。
    2016-12-12
  • CentOS7防火墻和端口相關(guān)命令介紹

    CentOS7防火墻和端口相關(guān)命令介紹

    大家好,本篇文章主要講的是CentOS7防火墻和端口相關(guān)命令介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • CentOS7安裝iptables防火墻的方法

    CentOS7安裝iptables防火墻的方法

    本篇文章主要介紹了CentOS7安裝iptables防火墻的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • 淺談Linux條件變量的使用

    淺談Linux條件變量的使用

    下面小編就為大家?guī)?lái)一篇淺談Linux條件變量的使用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • VirtualBox 未指定要bridged的網(wǎng)絡(luò)界面的解決辦法

    VirtualBox 未指定要bridged的網(wǎng)絡(luò)界面的解決辦法

    這篇文章主要介紹了VirtualBox 未指定要bridged的網(wǎng)絡(luò)界面的解決辦法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家解決遇到這樣的問(wèn)題,需要的朋友可以參考下
    2017-10-10
  • 基于?Apache?的?httpd?文件服務(wù)器詳解

    基于?Apache?的?httpd?文件服務(wù)器詳解

    httpd?HTTP?Daemon,超文本傳輸協(xié)議守護(hù)進(jìn)程的簡(jiǎn)稱,運(yùn)行于網(wǎng)頁(yè)服務(wù)器后臺(tái),等待傳入服務(wù)器請(qǐng)求的軟件,這篇文章主要介紹了基于?Apache?的?httpd?文件服務(wù)器,需要的朋友可以參考下
    2024-07-07

最新評(píng)論