佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > linux之虛擬內(nèi)存相關(guān)介紹

linux之虛擬內(nèi)存相關(guān)介紹

熱門標(biāo)簽:百度競(jìng)價(jià)點(diǎn)擊價(jià)格的計(jì)算公式 電話機(jī)器人搭建 解決方案 外呼系統(tǒng) 家政服務(wù)網(wǎng)絡(luò) 服務(wù)器配置 美團(tuán) 硅谷的囚徒呼叫中心
什么是虛存?為什么需要它?

  我們知道程序代碼和數(shù)據(jù)必須駐留在內(nèi)存中才能得以運(yùn)行,然而系統(tǒng)內(nèi)存數(shù)量很有限,往往不能容納一個(gè)完整程序的所有代碼和數(shù)據(jù),更何況在多任務(wù)系統(tǒng)中,可能需要同時(shí)打開子處理程序,畫圖程序,瀏覽器等很多任務(wù),想讓內(nèi)存駐留所有這些程序顯然不太可能。因此首先能想到的就是將程序分割成小份,只讓當(dāng)前系統(tǒng)運(yùn)行它所有需要的那部分留在內(nèi)存,其它部分都留在硬盤。當(dāng)系統(tǒng)處理完當(dāng)前任務(wù)片段后,再?gòu)耐獯嬷姓{(diào)入下一個(gè)待運(yùn)行的任務(wù)片段。的確,老式系統(tǒng)就是這樣處理大任務(wù)的,而且這個(gè)工作是由程序員自行完成。但是隨著程序語(yǔ)言越來(lái)越高級(jí),程序員對(duì)系統(tǒng)體系的依賴程度降低了,很少有程序員能非常清楚的駕馭系統(tǒng)體系,因此放手讓程序員負(fù)責(zé)將程序片段化和按需調(diào)入輕則降低效率,重則使得機(jī)器崩潰;再一個(gè)原因是隨著程序越來(lái)越豐富,程序的行為幾乎無(wú)法準(zhǔn)確預(yù)測(cè),程序員自己都很難判斷下一步需要載入哪段程序。因此很難再靠預(yù)見性來(lái)靜態(tài)分配固定大小的內(nèi)存,然后再機(jī)械地輪換程序片進(jìn)入內(nèi)存執(zhí)行。系統(tǒng)必須采取一種能按需分配而不需要程序員干預(yù)的新技術(shù)。

  虛擬內(nèi)存(之所以稱為虛擬內(nèi)存,是和系統(tǒng)中的邏輯內(nèi)存和物理內(nèi)存相對(duì)而言的,邏輯內(nèi)存是站在進(jìn)程角度看到的內(nèi)存,因此是程序員關(guān)心的內(nèi)容。而物理內(nèi)存是站在處理器角度看到的內(nèi)存,由操作系統(tǒng)負(fù)責(zé)管理。虛擬內(nèi)存可以說(shuō)是映射到這兩種不同視角內(nèi)存的一個(gè)技術(shù)手段。)技術(shù)就是一種由操作系統(tǒng)接管的按需動(dòng)態(tài)內(nèi)存分配的方法,它允許程序不知不覺中使用大于實(shí)際物理空間大小的存儲(chǔ)空間(其實(shí)是將程序需要的存儲(chǔ)空間以頁(yè)的形式分散存儲(chǔ)在物理內(nèi)存和磁盤上),所以說(shuō)虛擬內(nèi)存徹底解放了程序員,從此程序員不用過(guò)分關(guān)心程序的大小和載入,可以自由編寫程序了,繁瑣的事情都交給操作系統(tǒng)去做吧。

實(shí)現(xiàn)虛擬內(nèi)存
  虛擬內(nèi)存是將系統(tǒng)硬盤空間和系統(tǒng)實(shí)際內(nèi)存聯(lián)合在一起供進(jìn)程使用,給進(jìn)程提供了一個(gè)比內(nèi)存大得多的虛擬空間。在程序運(yùn)行時(shí),只要把虛擬地址空間的一小部分映射到內(nèi)存,其余都存儲(chǔ)在硬盤上(也就是說(shuō)程序虛擬空間就等于實(shí)際物理內(nèi)存加部分硬盤空間)。當(dāng)被訪問(wèn)的虛擬地址不在內(nèi)存時(shí),則說(shuō)明該地址未被映射到內(nèi)存,而是被存貯在硬盤中,因此需要的虛擬存儲(chǔ)地址隨即被調(diào)入到內(nèi)存;同時(shí)當(dāng)系統(tǒng)內(nèi)存緊張時(shí),也可以把當(dāng)前不用的虛擬存儲(chǔ)空間換出到硬盤,來(lái)騰出物理內(nèi)存空間。系統(tǒng)如此周而復(fù)始地運(yùn)轉(zhuǎn)——換入、換出,而用戶幾乎無(wú)法查覺,這都是拜虛擬內(nèi)存機(jī)制所賜。

  Linux的swap分區(qū)就是硬盤專門為虛擬存儲(chǔ)空間預(yù)留的空間。經(jīng)驗(yàn)大小應(yīng)該是內(nèi)存的兩倍左右。有興趣的話可以使用 swapon -s 查看交換分區(qū)大小。

  大道理很好理解,無(wú)非是用內(nèi)存和硬盤空間合成為虛擬內(nèi)存空間。但是這一過(guò)程中反復(fù)運(yùn)行的地址映射(虛擬地址映射到物理地址)和虛擬地址換入換出卻值得仔細(xì)推敲。系統(tǒng)到底是怎么樣把虛擬地址映射到物理地址上的呢??jī)?nèi)存又如何能不斷地和硬盤之間換入換出虛擬地址呢?

  利用段機(jī)制能否回答上述問(wèn)題呢?邏輯地址通過(guò)段機(jī)制后變?yōu)橐粋€(gè)32位的地址,足以覆蓋4G的內(nèi)存空間,當(dāng)程序需要的虛擬地址不在內(nèi)存時(shí),只依靠段機(jī)制很難進(jìn)行虛擬空間地?fù)Q入換出,因?yàn)椴淮蠓奖惆颜未笮〉奶摂M空間在內(nèi)存和硬盤之間調(diào)來(lái)調(diào)去(老式系統(tǒng)中,會(huì)笨拙地?fù)Q出整段內(nèi)存甚至整個(gè)進(jìn)程,想想這樣做會(huì)有那些惡果吧?。?。所以很有必要尋找一個(gè)更小更靈活的存儲(chǔ)表示單位,這樣才方便虛擬地址在硬盤和內(nèi)存之間調(diào)入調(diào)出。這個(gè)更小的存儲(chǔ)管理單位便是頁(yè)(4K大?。?。管理頁(yè)換入換出的機(jī)制被稱為頁(yè)機(jī)制。

  因?yàn)槭褂庙?yè)機(jī)制的原因,通過(guò)段機(jī)制轉(zhuǎn)換得到的地址僅僅是作為一個(gè)中間地址——線性地址,該地址不代表實(shí)際物理地址,而是代表整個(gè)進(jìn)程的虛擬空間地址。在線性地址的基礎(chǔ)上,頁(yè)機(jī)制接著會(huì)處理線性地址映射:當(dāng)需要的線性地址(虛擬空間地址)不在內(nèi)存時(shí),便以頁(yè)為單位從磁盤中調(diào)入需要的虛擬內(nèi)存;當(dāng)內(nèi)存不夠時(shí),又會(huì)以頁(yè)為單位把內(nèi)存中虛擬空間的換出到磁盤上。可見,利用頁(yè)來(lái)管理內(nèi)存和磁盤(虛擬內(nèi)存)大大方便了內(nèi)存管理的工作。毫無(wú)疑問(wèn),頁(yè)機(jī)制和虛擬內(nèi)存管理簡(jiǎn)直是“絕配”。

使用頁(yè)機(jī)制,4G空間被分成2的20次方個(gè)4K大小的頁(yè)面(頁(yè)面也可定為4M大小),因此定位頁(yè)面需要的索引表(頁(yè)表)中每個(gè)索引項(xiàng)至少需要20位,但是在頁(yè)表項(xiàng)中往往還需要附加一些頁(yè)屬性,所以頁(yè)表項(xiàng)實(shí)際為32位,其中12位用來(lái)存放諸如“頁(yè)是否存在于內(nèi)存”或“頁(yè)的權(quán)限”等信息。

前面我們提到了線性地址是32位。它其中高20位是對(duì)頁(yè)表的索引,低12位則給出了頁(yè)面中的偏移。線性地址經(jīng)過(guò)頁(yè)表找到頁(yè)面基地址后和低12位偏移量相加就形成了最終需要的物理地址了。

在實(shí)際使用中,并非所有頁(yè)表項(xiàng)都是被存放在一個(gè)大頁(yè)表里,因?yàn)槊總€(gè)頁(yè)表項(xiàng)占4個(gè)字節(jié),如果要在一個(gè)表中存放2的20次方個(gè)頁(yè)表項(xiàng),就需要4M的連續(xù)存儲(chǔ)空間。這么大的連續(xù)空間可不好找,因此往往會(huì)把頁(yè)表分級(jí)存儲(chǔ),比如分兩級(jí),那么每級(jí)頁(yè)表只需要4k連續(xù)空間了。

  兩級(jí)頁(yè)表搜索如同看章回小說(shuō),先找到在哪一章里,然后在找在該章下的哪一節(jié)。具體過(guò)程看看下圖:

綜上所述,地址轉(zhuǎn)換工作需要兩種技術(shù),一是段機(jī)制,二是頁(yè)機(jī)制。段機(jī)制處理邏輯地址向線性地址的映射;頁(yè)機(jī)制則負(fù)責(zé)把線性地址映射為物理地址。兩級(jí)映射共同完成了從程序員看到的邏輯地址轉(zhuǎn)換到處理器看到的物理地址這一艱巨任務(wù)。

  你可以將這兩種機(jī)制分別比作一個(gè)地址轉(zhuǎn)換函數(shù),段機(jī)制的變量是邏輯地址,函數(shù)值是線性地址;頁(yè)機(jī)制的變量是線性地址,函數(shù)值是物理地址。地址轉(zhuǎn)換過(guò)程如下所示。

  邏輯地址——(段函數(shù))——>線性地址——(頁(yè)函數(shù))——>物理地址。

  雖然段機(jī)制和頁(yè)機(jī)制都參與映射,但它們分工不同,而且相互獨(dú)立互不干擾,彼此之間不必知道對(duì)方是否存在。

  下面我們結(jié)合Linux實(shí)例簡(jiǎn)要地看看段頁(yè)機(jī)制如何使用。

Linux中的分段策略
  段機(jī)制在Linux里用得有限,并沒有被完全利用。每個(gè)任務(wù)并未分別安排各自獨(dú)立的數(shù)據(jù)段,代碼段,而是僅僅最低限度的利用段機(jī)制來(lái)隔離用戶數(shù)據(jù)和系統(tǒng)數(shù)據(jù)——Linux只安排了四個(gè)范圍一樣的段,內(nèi)核數(shù)據(jù)段,內(nèi)核代碼段,用戶數(shù)據(jù)段,用戶代碼段,它們都覆蓋0-4G的空間,所不同的是各段屬性不同,內(nèi)核段特權(quán)級(jí)為0,用戶段特權(quán)級(jí)為3。這樣分段,避免了邏輯地址到線性地址的轉(zhuǎn)換步驟(邏輯地址就等于線性地址),但仍然保留了段的等級(jí)這層最基本保護(hù)。

每個(gè)用戶進(jìn)程都可以看到4G大小的線性空間,其中0-3G是用戶空間,用戶態(tài)進(jìn)程可以直接訪問(wèn);從3G-4G空間為內(nèi)核空間,存放內(nèi)核代碼和數(shù)據(jù),只有內(nèi)核態(tài)進(jìn)程能夠直接訪問(wèn),用戶態(tài)進(jìn)程不能直接訪問(wèn),只能通過(guò)系統(tǒng)調(diào)用和中斷進(jìn)入內(nèi)核空間,而這時(shí)就要進(jìn)行的特權(quán)切換。

說(shuō)到特權(quán)切換,就離不開任務(wù)門,陷阱門/中斷門等概念。陷阱門和中斷門是在發(fā)生陷阱和中斷時(shí),進(jìn)入內(nèi)核空間的通道。調(diào)用門是用戶空間程序相互訪問(wèn)時(shí)所需要的通道,任務(wù)門比較特殊,它不含任何地址,而是服務(wù)于任務(wù)切換(但linux任務(wù)切換時(shí)并未真正采用它,它太麻煩了)。

對(duì)于各種門系統(tǒng)都會(huì)有對(duì)應(yīng)的門描述符,和段描述符結(jié)構(gòu)類似,門描述符也是由對(duì)應(yīng)的門選擇字索引,并且最終會(huì)產(chǎn)生一個(gè)指向特定段內(nèi)偏移地址的指針。這個(gè)指針指向的就是將要進(jìn)入的入口。利用門的目的就是保證入口可控,不至于進(jìn)入到內(nèi)核中不該訪問(wèn)的位置。

Linux中的分頁(yè)策略
  看看linux中如何使用分頁(yè)。

  Linux中每個(gè)進(jìn)程都會(huì)有各自不同的頁(yè)表,也就是說(shuō)進(jìn)程的映射函數(shù)互不相同,保證每個(gè)進(jìn)程虛擬地址不會(huì)映射到相同的物理地址上。這是因?yàn)檫M(jìn)程之間必須相互獨(dú)立,各自的數(shù)據(jù)必須隔離,防止信息泄漏。

  需要注意的是,內(nèi)核作為必須保護(hù)的單獨(dú)部分,它有自己獨(dú)立的頁(yè)表來(lái)映射內(nèi)核空間(并非全部空間,僅僅是物理內(nèi)存大小的空間),該頁(yè)表(swapper_pg_dir)被靜態(tài)分配,它只來(lái)映射內(nèi)核空間(swapper_pg_dir只用到768項(xiàng)以后的項(xiàng)——768個(gè)頁(yè)目錄可映射3G空間)。這個(gè)獨(dú)立頁(yè)表保證了內(nèi)核虛擬空間獨(dú)立于其他用戶程序空間,也就是說(shuō)其他進(jìn)程通常狀態(tài)下和內(nèi)核是沒有聯(lián)系的(在編譯內(nèi)核的時(shí)候,內(nèi)核代碼被指定鏈接到3G以上空間),因而內(nèi)核數(shù)據(jù)也就自然被保護(hù)起來(lái)了。

  那么在用戶進(jìn)程需要訪問(wèn)內(nèi)核空間時(shí)如何做呢?

  Linux采用了個(gè)巧妙的方法:用戶進(jìn)程頁(yè)表的前768項(xiàng)映射進(jìn)程空間(3G,因?yàn)長(zhǎng)DT 中只指定基地址為0,范圍只能到0xc0000000),如果進(jìn)程要訪問(wèn)內(nèi)核空間,如調(diào)用系統(tǒng)調(diào)用,則進(jìn)程的頁(yè)目錄中768項(xiàng)后的表項(xiàng)將指向swapper_pg_dir的768項(xiàng)后的項(xiàng),所以一旦用戶陷入內(nèi)核,就開始使用內(nèi)核的頁(yè)表swapper_pg_dir了,也就是說(shuō)可以訪問(wèn)內(nèi)核空間了。

標(biāo)簽:北海 撫州 烏蘭察布 臨沂 韶關(guān) 防城港 南昌 邢臺(tái)

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《linux之虛擬內(nèi)存相關(guān)介紹》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    迁西县| 平江县| 广宗县| 廉江市| 景德镇市| 兰考县| 深圳市| 益阳市| 乌审旗| 皮山县| 秦皇岛市| 营山县| 东明县| 雷波县| 新昌县| 江陵县| 新闻| 吉林省| 平顶山市| 民勤县| 织金县| 绥棱县| 磐安县| 丰镇市| 瑞金市| 濉溪县| 乌审旗| 喀什市| 恩平市| 长汀县| 东港市| 江北区| 锡林浩特市| 昌宁县| 海宁市| 福泉市| 永吉县| 齐河县| 合阳县| 化德县| 涿州市|