亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺析操作系統(tǒng)中的虛擬地址與物理地址

 更新時(shí)間:2021年06月21日 11:34:45   作者:飛天小牛肉  
本文主要介紹了操作系統(tǒng)中的虛擬地址與物理地址。在早期的計(jì)算機(jī)中,要運(yùn)行一個(gè)程序,會(huì)把這些程序全都裝入內(nèi)存,程序都是直接運(yùn)行在內(nèi)存上的,也就是說(shuō)程序中訪問(wèn)的內(nèi)存地址都是實(shí)際的物理內(nèi)存地址。那當(dāng)程序同時(shí)運(yùn)行多個(gè)程序時(shí),操作系統(tǒng)是如何為這些程序分配內(nèi)存的呢

一、前言

先解釋下一個(gè)困擾了我很久的問(wèn)題:虛擬地址(vitural address)和邏輯地址(logical address)的區(qū)別。

大部分操作系統(tǒng)的書(shū)籍要么寫(xiě)的是虛擬地址,要么寫(xiě)的是邏輯地址,看的我一臉懵逼。

在《深入理解 Linux 內(nèi)核》這本書(shū)中終于找到了確切的答案,這里我就不寫(xiě)出來(lái)了,扣概念的話這倆確實(shí)是有些區(qū)別的,不過(guò)對(duì)于我們?nèi)粘J褂靡约袄斫獠僮飨到y(tǒng)來(lái)說(shuō)的話,暫且可以把虛擬地址和邏輯地址理解為同一個(gè)意思。

二、你看到的所有地址都不是真的

下面這段 C 代碼摘錄自《操作系統(tǒng)導(dǎo)論 - [美] 雷姆茲·H.阿帕希杜塞爾》,依次打印出 main 函數(shù)的地址,由 malloc(類似于 Java 中的 new 操作)返回的堆空間分配的值,以及棧上一個(gè)整數(shù)的地址:

得到以下輸出:

我們需要知道的是,所有這些打印出來(lái)的地址都是虛擬的,在物理內(nèi)存中這些地址并不真實(shí)存在,它們最終都將由操作系統(tǒng)和 CPU 硬件翻譯成真正的物理地址,然后才能從真實(shí)的物理位置獲取該地址的值。

OK,上述就當(dāng)作一個(gè)引子,讓各位對(duì)物理地址和虛擬地址有個(gè)直觀的理解,下面正文開(kāi)始。

三、物理尋址 Physical Addressing

物理地址的概念很好理解,你可以把它稱為真正的地址?!渡钊肜斫庥?jì)算機(jī)系統(tǒng) - 第 3 版》中給出的物理地址(physical address)的定義如下:

計(jì)算機(jī)系統(tǒng)的主存被組織成一個(gè)由 M 個(gè)連續(xù)的字節(jié)大小的單元組成的數(shù)組。每字節(jié)都有一個(gè)唯一的物理地址。

比如說(shuō),第一個(gè)字節(jié)的物理地址是 0,接下來(lái)的字節(jié)地址是 1,再下一個(gè)是 2,以此類推,給定這種簡(jiǎn)單的結(jié)構(gòu),CPU 訪問(wèn)內(nèi)存的最自然的方式就是使用這樣的物理地址。我們把這種方式稱為物理尋址(physical addressing)。

舉個(gè)例子,比如說(shuō)當(dāng)程序執(zhí)行了一條加載指令,指令內(nèi)容是從物理地址 4 中讀取 4 字節(jié)字傳送到某個(gè)寄存器中。

物理尋址過(guò)程如下:當(dāng) CPU 執(zhí)行到這條指令時(shí),會(huì)生成物理地址 4,然后通過(guò)內(nèi)存主線,把它傳遞給內(nèi)存,內(nèi)存取出從物理地址 4 處開(kāi)始的 4 字節(jié)字,并將它返回給 CPU,CPU 會(huì)將它存放到指定的寄存器中??聪聢D:

其實(shí)不難發(fā)現(xiàn),物理尋址這種方式,每一個(gè)程序都直接訪問(wèn)物理內(nèi)存,其實(shí)是存在重大缺陷的:

1)首先,用戶程序可以尋址內(nèi)存的任意一個(gè)字節(jié),它們就可以很容易地破壞操作系統(tǒng),從而使系統(tǒng)慢慢地停止運(yùn)行。

2)再次,這種尋址方式使得操作系統(tǒng)中同時(shí)運(yùn)行兩個(gè)或以上的程序幾乎是不可能的。

舉個(gè)例子,我們打開(kāi)了三個(gè)相同的程序(計(jì)算器),都執(zhí)行到某一步。比方說(shuō),用戶在這三個(gè)程序的界面上分別輸入了 10、100、1000,其對(duì)應(yīng)的指令就是把用戶輸入的數(shù)字保存在內(nèi)存中的某個(gè)地址中。如果這個(gè)位置只能保存一個(gè)數(shù),那應(yīng)該保存哪個(gè)呢?這不就沖突了嗎?

再舉個(gè)例子,摘自《現(xiàn)代操作系統(tǒng) - 第 3 版》:

一個(gè)程序給物理內(nèi)存地址 1000 賦值也就是存入了一些數(shù)據(jù)后,另一個(gè)程序也同樣給這個(gè)地址賦值,那么第二個(gè)程序的賦值會(huì)覆蓋掉第一個(gè)程序所賦的值,這會(huì)造成兩個(gè)程序同時(shí)崩潰。

當(dāng)然了,我們也說(shuō)了是幾乎不可能,不是完全不可能,還是有一些方法可以在物理尋址這種方式下實(shí)現(xiàn)多個(gè)程序并發(fā)運(yùn)行的。

最簡(jiǎn)單的方法就是:首先,將空閑的進(jìn)程存儲(chǔ)在磁盤(pán)上,這樣當(dāng)它們不運(yùn)行時(shí)就不會(huì)占用內(nèi)存,然后,讓一個(gè)程序(或者說(shuō)進(jìn)程)單獨(dú)占用全部?jī)?nèi)存運(yùn)行一小段時(shí)間,當(dāng)發(fā)生上下文切換的時(shí)候,就停止這個(gè)進(jìn)程,并將它所有的狀態(tài)信息保存在磁盤(pán)上,再加載其他進(jìn)程的狀態(tài)信息,然后運(yùn)行一段時(shí)間...... 只要在某一個(gè)時(shí)間內(nèi)存中只有一個(gè)程序,那么就不會(huì)發(fā)生上述所說(shuō)的地址沖突。這就實(shí)現(xiàn)了一種比較粗糙的并發(fā)。

為什么說(shuō)他是粗糙的呢,因?yàn)檫@種方法有一個(gè)問(wèn)題:將全部的內(nèi)存信息保存到磁盤(pán)太慢了!特別是當(dāng)內(nèi)存增長(zhǎng)的時(shí)候。

因此,我們考慮把進(jìn)程對(duì)應(yīng)的內(nèi)存一直留在物理內(nèi)存中,在發(fā)生上下文切換的時(shí)候就切換到特定的區(qū)域。

如下圖所示,有 3 個(gè)進(jìn)程(A、B、C),每個(gè)進(jìn)程擁有從 512KB 物理內(nèi)存中切出來(lái)給它們的一小部分內(nèi)存,可以理解為這 3 個(gè)進(jìn)程共享物理內(nèi)存:

顯然,這種方式是存在一定安全隱患的。畢竟如果各個(gè)進(jìn)程之間可以隨意讀取、寫(xiě)入內(nèi)容的話那就亂套了。

那么如何對(duì)每個(gè)進(jìn)程使用的地址進(jìn)行保護(hù)(protection)呢?繼續(xù)使用物理內(nèi)存模型肯定是不行了,因此操作系統(tǒng)創(chuàng)造了一個(gè)新的內(nèi)存抽象,引入了一個(gè)新的內(nèi)存模型,那就是虛擬地址空間,很多書(shū)中都會(huì)直接稱呼為 “地址空間(Address Space)”。

四、虛擬尋址 Virtual Addressing

我先通俗地解釋下虛擬地址空間和虛擬地址的概念,直接上書(shū)中的定義讀起來(lái)有點(diǎn)生澀。

就是說(shuō)每個(gè)進(jìn)程的棧啊、堆啊、代碼段啊等等它們的實(shí)際物理內(nèi)存地址對(duì)于這個(gè)進(jìn)程來(lái)說(shuō)是不可見(jiàn)的,誰(shuí)也不能直接訪問(wèn)這個(gè)物理地址。

那我們?cè)趺慈ピL問(wèn)這個(gè)進(jìn)程呢?

操作系統(tǒng)會(huì)給每個(gè)進(jìn)程分配一個(gè)虛擬地址空間(vitural address),每個(gè)進(jìn)程包含的棧、堆、代碼段這些都會(huì)從這個(gè)地址空間中被分配一個(gè)地址,這個(gè)地址就被稱為虛擬地址。底層指令寫(xiě)入的地址也是虛擬地址。

每個(gè)進(jìn)程都擁有一個(gè)自己的地址空間,并且獨(dú)立于其他進(jìn)程的地址空間。也就是說(shuō)一個(gè)進(jìn)程中的虛擬地址 28 所對(duì)應(yīng)的物理地址與另一個(gè)進(jìn)程中的虛擬地址 28 所對(duì)應(yīng)的物理地址是不同的,這樣就不會(huì)發(fā)生沖突了。

可以這么理解,物理地址就是一個(gè)倉(cāng)庫(kù),虛擬地址就是一個(gè)門(mén)牌,比方說(shuō)一共有三十個(gè)門(mén)牌,那么所有的進(jìn)程都能看見(jiàn)這三十個(gè)門(mén)牌,但是他們看見(jiàn)的某個(gè)相同門(mén)牌,指向的并不是同一個(gè)倉(cāng)庫(kù)。

OK,下面再來(lái)看《現(xiàn)代操作系統(tǒng) - 第 3 版》書(shū)中對(duì)于地址空間的解釋,應(yīng)該很容易理解了:

地址空間是一個(gè)進(jìn)程可用于尋址內(nèi)存的一套地址集合。每個(gè)進(jìn)程都有一個(gè)自己的地址空間,并且這個(gè)地址空間獨(dú)立于其他進(jìn)程的地址空間(除了在一些特殊情況下進(jìn)程需要共享它們的地址空間外)。

地址空間的概念非常通用,并且在很多場(chǎng)合中出現(xiàn)。比如電話號(hào)碼,在美國(guó)和很多其他國(guó)家,一個(gè)本地電話號(hào)碼通常是一個(gè) 7 位的數(shù)字。因此,電話號(hào)碼的地址空間是從 0 000 000 到 9 999 999。

地址空間也可以是非數(shù)字的,以 “.com” 結(jié)尾的網(wǎng)絡(luò)域名的集合也是地址空間。這個(gè)地址空間是由所有包含 2~63 個(gè)字符并且后面跟著 “.com” 的字符串組成的,組成這些字符串的字符可以是字母、數(shù)字和連字符。

到現(xiàn)在你應(yīng)該已經(jīng)明白地址空間的概念了,它是很簡(jiǎn)單的。

有了虛擬地址空間后,CPU 就可以通過(guò)生成一個(gè)虛擬地址來(lái)訪問(wèn)主存,這個(gè)虛擬地址在被送到內(nèi)存之前會(huì)先被轉(zhuǎn)換成合適的物理地址,這個(gè)虛擬地址到物理地址的轉(zhuǎn)換過(guò)程稱為 地址翻譯/地址轉(zhuǎn)換(address translation)。

地址翻譯需要 CPU 硬件和操作系統(tǒng)的密切合作:CPU 上的內(nèi)存管理單元(Memory Management Unit,MMU)就是專門(mén)用來(lái)進(jìn)行虛擬地址到物理地址的轉(zhuǎn)換的,不過(guò) MMU 需要借助存放在內(nèi)存中的查詢表,而這張表的內(nèi)容正是由操作系統(tǒng)進(jìn)行管理的。

那么,上述這一套 CPU 生成虛擬地址并進(jìn)行地址翻譯的流程就是虛擬尋址(virtual addressing)。舉個(gè)例子,看下圖:

以上就是淺析虛擬地址與物理地址的詳細(xì)內(nèi)容,更多關(guān)于虛擬地址 物理地址的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 用C語(yǔ)言判斷字符是否為空白字符或特殊字符的方法

    用C語(yǔ)言判斷字符是否為空白字符或特殊字符的方法

    這篇文章主要介紹了用C語(yǔ)言判斷字符是否為空白字符或特殊字符的方法,分別為isspace()函數(shù)的使用和ispunct()函數(shù)的使用,需要的朋友可以參考下
    2015-08-08
  • 淺析C++字節(jié)對(duì)齊容易被忽略的兩個(gè)問(wèn)題

    淺析C++字節(jié)對(duì)齊容易被忽略的兩個(gè)問(wèn)題

    今天我就和大家分享一下C++字節(jié)對(duì)齊容易被忽略的兩個(gè)問(wèn)題。以下問(wèn)題也是我實(shí)際開(kāi)發(fā)工作中遇到的,如果有不同意見(jiàn)歡迎交流
    2013-07-07
  • C++實(shí)現(xiàn)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的數(shù)學(xué)算法

    C++實(shí)現(xiàn)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的數(shù)學(xué)算法

    這篇文章和大家分享一下我個(gè)人對(duì)十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)的想法,目前暫時(shí)更新只整數(shù)十進(jìn)制的轉(zhuǎn)換,后續(xù)會(huì)更新帶有小數(shù)的進(jìn)制轉(zhuǎn)換,代碼使用c++實(shí)現(xiàn)
    2021-09-09
  • C++學(xué)習(xí)筆記之類成員指針

    C++學(xué)習(xí)筆記之類成員指針

    類成員指針時(shí)指可以指向類的非靜態(tài)成員的指針,下面這篇文章主要給大家介紹了關(guān)于C++類成員指針的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • 純C++代碼詳解二叉樹(shù)相關(guān)操作

    純C++代碼詳解二叉樹(shù)相關(guān)操作

    二叉樹(shù)(Binary?tree)是樹(shù)形結(jié)構(gòu)的一個(gè)重要類型。許多實(shí)際問(wèn)題抽象出來(lái)的數(shù)據(jù)結(jié)構(gòu)往往是二叉樹(shù)形式。本文將通過(guò)代碼為大家詳細(xì)講講C++二叉樹(shù)的一些常規(guī)操作,感興趣的可以學(xué)習(xí)一下
    2022-07-07
  • C++實(shí)現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解

    C++實(shí)現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解

    拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個(gè)重載,因此顯式的定義了拷貝構(gòu)造,那么編譯器也不再默認(rèn)生成構(gòu)造函數(shù)。本文主要介紹了C++實(shí)現(xiàn)拷貝構(gòu)造函數(shù)的方法,需要的可以參考一下
    2022-09-09
  • C語(yǔ)言實(shí)現(xiàn)桶排序的方法示例

    C語(yǔ)言實(shí)現(xiàn)桶排序的方法示例

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)桶排序的方法,簡(jiǎn)單描述了桶排序的概念、原理并結(jié)合實(shí)例形式分析了C語(yǔ)言實(shí)現(xiàn)桶排序算法的具體操作技巧,需要的朋友可以參考下
    2018-01-01
  • C語(yǔ)言實(shí)現(xiàn)基于最大堆和最小堆的堆排序算法示例

    C語(yǔ)言實(shí)現(xiàn)基于最大堆和最小堆的堆排序算法示例

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)基于最大堆和最小堆的堆排序算法示例,分別是基于最大堆的升序排序和基于最小堆的降序排序?qū)嵗?需要的朋友可以參考下
    2016-06-06
  • C++設(shè)計(jì)模式之組合模式

    C++設(shè)計(jì)模式之組合模式

    這篇文章主要介紹了C++設(shè)計(jì)模式之組合模式,本文講解什么是組合模式、組合模式的優(yōu)點(diǎn)、組合模式實(shí)例等內(nèi)容,需要的朋友可以參考下
    2014-09-09
  • C語(yǔ)言?推理證明帶環(huán)鏈表詳細(xì)過(guò)程

    C語(yǔ)言?推理證明帶環(huán)鏈表詳細(xì)過(guò)程

    單鏈表中同樣也有具有挑戰(zhàn)性的題目,鏈表的帶環(huán)問(wèn)題可以說(shuō)是眾多難題中的佼佼者,在這里可能更看重的是邏輯推理和證明的過(guò)程
    2022-04-04

最新評(píng)論