選單

CPU竟然才是管理記憶體的大BOSS ?

對於C/C++程式設計師來說,記憶體分配再正常不過,C語言中的malloc:

int* a = (int*)malloc(sizeof(int));

C++中的new:

int* a = new int(10);

接下來的問題是變數a佔用的記憶體是誰給我們分配的呢?

答案是執行在使用者態的記憶體分配器,如果你願意,也可以繞過記憶體分配器自己來管理記憶體。

接下來的問題是a佔用的記憶體在哪裡呢?

答案是程序地址空間中的堆區,堆區在這裡:

CPU竟然才是管理記憶體的大BOSS ?

記憶體中真的有像圖中這樣的佈局嗎?

答案是:

沒有

這就是所謂的虛擬記憶體。

既然是虛擬記憶體那麼這裡的堆區又是從哪裡來的呢?

答案是作業系統。

當我們在C/C++中分配記憶體時,記憶體分配器從堆區中找到可用記憶體,但如果沒有找到則向作業系統申請。

那麼作業系統又是從哪裡找到的記憶體呢?

答案是:作業系統從物理記憶體中找到一塊可用記憶體分配出去。

問題來了,既然作業系統管理的是物理記憶體,而作業系統分配給程序的又是虛擬記憶體,精神分裂啊有沒有,這是怎麼一回事呢?

原來這並不衝突,作業系統會為每個程序分配一張表,記錄了從虛擬記憶體到物理記憶體的對映,這張表就叫頁表。

CPU竟然才是管理記憶體的大BOSS ?

因此,儘管作業系統管理的是物理記憶體,但程序或者說程式設計師是看不到物理記憶體的,我們只能看到虛擬記憶體,程式執行時在傳送記憶體讀寫指令時MMU會將虛擬記憶體轉換為物理記憶體。

接下來的問題是頁表在哪裡?

答案是:

在記憶體中

你可以將頁表放在記憶體中的任何位置上,只要能告訴CPU在哪裡即可。

誰來負責構造頁表呢?答案是作業系統,作業系統負責建立頁表,頁表本質上就是一個數組,處理器規定頁表的格式,作業系統按照這種格式構建好頁表,建立好後即可告訴CPU。

該怎樣告訴CPU呢?

答案是:透過寫特定的暫存器。

CPU中有特定的暫存器,以x86處理器為例,其中的控制暫存器cr3就用來儲存頁表的地址,假設指標pagetable指向頁表,那麼可以這樣設定:

mov $(pagetable), %eax

mov %eax, %cr3

pagetable必須是物理地址,頁表本身就用來將虛擬地址轉為物理地址,因此向cr3中寫入虛擬地址是沒有道理的。

接下來的問題是什麼時候將頁表寫入cr3暫存器呢?

答案是:很多時候,作業系統初始化階段、程序切換時等。

現在你應該知道了吧,其實記憶體管理(段式管理、頁式管理)是處理器提供的一種機制,作業系統只是這種機制的使用者,我們常說的虛擬記憶體是處理器本身的一種能力,

如果處理器本身不提供這種能力,那麼作業系統自己是很難高效實現虛擬記憶體的

CPU才是管理記憶體真正的大boss。

實際上如果你去看類似x86這樣的處理器程式設計手冊時就會發現,我們在作業系統課中熟悉的很多概念其實是處理器這種硬體提供的,作業系統僅僅是利用這些硬體的一層軟體。

因此,

從這個角度看,作業系統僅僅是CPU的一個“驅動程式”而已。

開啟App看更多精彩內容