Linux中的虛擬位址、物理地址和記憶體管理方式(一)

來源:互聯網
上載者:User

一、簡單介紹下早期的記憶體實現:(可略過)

        1、在早期的電腦中,運行一個程式的特點是:

            (1)會把這些程式全都裝入記憶體,

            (2)程式都是直接運行在記憶體上的,也就是說程式中訪問的記憶體位址都是實際的實體記憶體地址。

        2、在早起的記憶體實現方式中出現的問題:

            (1)當計算 機同時運行多個程式時,必須保證這些程式用到的記憶體總量要小於電腦實際實體記憶體的大小。

            (2)進程地址空間不隔離。進程間可以相互修改資料

            (3)記憶體使用量率低。運行一個進程,必須在記憶體中為它分配實際進程大小的空間(不管當前這些空間是否都會用到)

            (4)程式啟動並執行地址不確定。分配記憶體時,只是單純的從記憶體空間找一個足夠滿足進程要求的空間,所以進程啟動並執行地址具有隨機性。


二、虛擬位址技術

      為瞭解決上面的問題,一些大牛們就提出了傳說中的虛地址技術。即:在使用者進程和實際的實體記憶體之間加一個中介層(虛擬位址),讓使用者進程只能訪問虛擬位址,並且把虛擬位址物理地址轉換的實現交給作業系統。

      採用虛擬位址的特點:

        1、當建立進程時,

            (1)OS會為每個進程分配一個4G大小的虛擬位址空間,且每個進程都有3G的使用者空間和1G的核心空間。但最後這1G的核心空間中的內容對於不同進程來說是一樣的(之所以是4G大小,是因為在32位作業系統中,一個指標的大小是4btyes,所以能訪問的地址空間就是0x00000000~0xFFFFFFFF == 4G)。

            (2)這4G的虛擬位址空間是作業系統虛擬出來的,並不是真實存在的。

            (3)每個進程只能訪問自己的虛擬位址,無法訪問別的進程的虛擬位址。

            (4)雖然每個進程的虛擬位址都有4G大小,但並不是這4G的地址都可以由使用者任意使用。在Linux中,系統把虛擬位址劃分成2個部分(如所示):


註:1、任意一個時刻,在一個CPU上只有一個進程在運行。所以對於此CPU來講,在這一時刻,整個系統只存在一個4GB的虛擬位址空間,這個虛擬位址空間是面向此進程的。

       當進程發生切換的時候,虛擬位址空間也隨著切換。每個進程只有在啟動並執行時候,其虛擬位址空間才被運行它的CPU所知。在其它時刻,其虛擬位址空間對於CPU來說,是不可知的。所以儘管每個進程都可以有4
GB的虛擬位址空間,但在CPU眼中,只有一個虛擬位址空間存在。虛擬位址空間的變化,隨著進程切換而變化。

       2、核心空間與實體記憶體空間的映射和使用者空間與實體記憶體空間的映射方式是不同:

            雖然核心空間佔據了每個虛擬空間中的最高1GB位元組,但映射到實體記憶體卻總是從最低地址(0x00000000)開始的,之所以這麼規定,是為了在核心空間與實體記憶體之間建立簡單的線性映射關係。其中,3GB(0xC0000000)就是物理地址與虛擬位址之間的位移量,在Linux代碼中就叫做PAGE_OFFSET。
                
我們來看一下在include/asm/i386/page.h標頭檔中對核心空間中地址映射的說明及定義:

#define __PAGE_OFFSET           (0xC0000000)
……
#define PAGE_OFFSET             ((unsigned long)__PAGE_OFFSET)
#define __pa(x)                 ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x)                 ((void *)((unsigned long)(x)+PAGE_OFFSET))
對於核心空間而言,給定一個虛地址x,其物理地址為“x-
PAGE_OFFSET”,給定一個物理地址x,其虛地址為“x+ PAGE_OFFSET”。

這裡再次說明,宏__pa()僅僅把一個核心空間的虛地址映射到物理地址,

             這種方法決不適用於使用者空間,使用者空間的地址映射要複雜得多,它通過分頁機制完成。




(圖一)4G虛擬位址空間的整體結構



(圖二)核心空間分配圖


(圖三,地址分布圖)

        2、與虛擬位址相對的就是我們記憶體條實際的大小了。以本人PC為例:我用的是2G記憶體,那麼實際的物理地址空間就是:0x00000000~0x1FFFFFFF  

三、分段和分頁

          1、採用虛擬位址技術後出現的新問題是:虛擬位址和物理地址之間的映射方式。大牛們提出的解決方式就是分段、分頁和段頁式了。具體實現我們用一個例子來示範:

        eg:假設有兩個進程 A 和 B ,進程 A 所需記憶體大小為 10M ,其虛擬位址空間分布在 0x00000000 到 0x00A00000 ,進程 B 所需記憶體為 100M ,其虛擬位址空間分布為 0x00000000 到 0x06400000 。

       (1)採用分段的方式


       這種分段的映射方法雖然解決了上述中的問題(2)和問題(4),但並沒能解決問題(1)(3),即記憶體的使用效率問題。在分段的映射方法中,每次換入換出記憶體的都是整個程式,
這樣會造成大量的磁碟訪問操作,導致效率低下。所以這種映射方法還是稍顯粗糙,粒度比較大

       (2)採用分頁式

              分頁的基本方法是,將地址空間分成許多的頁。每頁的大小由 CPU 決定,然後由作業系統選擇頁的大小。目前 Inter 系列的 CPU 支援 4KB 或 4MB 的頁大小,而 PC 上目前都選擇使用 4KB 。按這種選擇, 4GB 虛擬位址空間共可以分成 1048576 個頁, 512M 的實體記憶體可以分為 131072 個頁。

              分頁的思想是程式運行時用到哪頁就為哪頁分配記憶體,沒用到的頁暫時保留在 硬碟上。

四、這裡對分段、分頁只做了一個簡單籠統的介紹,如果想更深入的理解底層的實現機制,請看下一篇

Linux中的虛擬位址、物理地址和記憶體管理方式(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.