Linux 記憶體管理 pt.1

鹹魚Linux運維發表於2023-04-27

哈嘍大家好,我是鹹魚

 

今天我們來學習一下 Linux 作業系統核心之一:記憶體

 

跟 CPU 一樣,記憶體也是作業系統最核心的功能之一,記憶體主要用來儲存系統和程式的指令、資料、快取等

 

關於記憶體的學習,我會盡量以通俗易懂的方式且分成多篇文章去講解

 

那麼今天在 pt.1 文章中,我們來學習一下 Linux 中的虛擬記憶體、實體記憶體和記憶體對映

 

Linux 記憶體

 

只有核心才可以直接訪問實體記憶體,程式是無法直接訪問實體記憶體的

 

  • 那麼程式是如何訪問實體記憶體?

 

Linux 核心給每個程式都提供了一個獨立的虛擬地址空間,並且這個空間是連續的,這樣程式就可以很方便的訪問到記憶體,準確來說是訪問到虛擬記憶體

 

又因為這個虛擬地址空間(虛擬記憶體)與實體記憶體相關聯,程式則是透過虛擬記憶體去訪問實體記憶體的

 

 

虛擬地址空間又被分成核心空間使用者空間,程式在使用者態時只能訪問虛擬使用者空間地址,在核心態可以訪問虛擬核心空間地址

 

對於不同位數字長(單個 CPU 指令可以處理資料的最大長度)的處理器(32位系統、64位系統),地址空間的範圍也不同

 

 

由上圖可以看到,32 位系統的核心空間佔 1G,位於最高處;剩下的 3G 是使用者空間

 

而 64 位系統的核心空間和使用者空間都是 128T,分別佔據整個記憶體空間的最高和最低處,剩下的中間部分是未定義的

 

雖然每個程式都有虛擬核心空間,但每個程式的虛擬核心空間記憶體關聯的都是相同的實體記憶體,方便程式切換到核心態後去訪問實體記憶體

 

實體地址空間是實體記憶體的範圍,虛擬地址空間是虛擬記憶體的範圍,實體地址空間中的每個實體地址都是實打實地指向了具體的儲存單元

 

虛擬地址空間中每個虛擬地址指向哪裡有 3 種情況:

  • 未分配,這個虛擬地址僅僅是個數字而已,沒有任何指向

  • 未緩衝,這個虛擬地址指向了磁碟的某個位元組儲存單元,裡面儲存了指令或者資料

  • 已緩衝,這個虛擬地址指向了實體記憶體的某個位元組儲存單元,裡面儲存了指令或者資料。

 

  • 虛擬記憶體的好處:

    • 避免使用者直接訪問實體記憶體,防止一些破壞性操作,保護作業系統

    • 每個程式都被分配了 4GB 的 虛擬地址空間,使用者可使用比實力實體記憶體更大的地址空間(用的時候才分配)

 

那麼當程式實際使用的時候,程式的虛擬記憶體是怎麼分配到實體記憶體的呢?

 

1.記憶體對映

並不是所有的虛擬記憶體都會被分配實體記憶體,只有那些實際使用的虛擬記憶體才分配實體記憶體,並且分配後的實體記憶體,是透過記憶體對映來管理的

 

記憶體對映,其實就是將虛擬記憶體地址對映到實體記憶體地址

 

為了完成記憶體對映,核心為每個程式都維護了一張頁表,用來記錄虛擬記憶體與實體記憶體的對映關係

 

頁表實際上儲存在 CPU 的記憶體管理單元 MMU 中。這樣,正常情況下,CPU 就可以直接透過硬體,找出要訪問的記憶體

 

 

這張頁表裡面有很多頁表項,每個頁表項的大小為 4KB。當程式訪問的虛擬記憶體被分配了實體記憶體之後,系統就會更新頁表,在頁表項中新增虛擬記憶體與實體記憶體的對映關係

 

  • 缺頁異常

如果程式要訪問的虛擬記憶體沒有被分配實體記憶體(即在頁表中找不到對映關係),就會產生一個缺頁異常中斷

 

這時候系統會進入核心空間分配實體記憶體、然後更新程式頁表,最後再返回使用者空間,恢復程式的執行

 

MMU 中有一個快取記憶體 TLB((Translation Lookaside Buffer,轉譯後備緩衝器),TLB 訪問速度要比 MMU 快得多

透過提高 TLB 快取使用率,可以提高 CPU 的記憶體訪問效能 

總結

在 Linux 中,為了提高記憶體利用率和系統可靠性,同時也為了不同程式之間的記憶體隔離,程式不能直接訪問到實體記憶體

 

Linux 為每一個程式都分配了一個虛擬記憶體,當程式實際使用的時候,虛擬記憶體才會被分配實體記憶體

 

Linux 透過記憶體對映的方式來實現透過虛擬記憶體去訪問實體記憶體,為了完成記憶體對映,核心為每個程式都維護了一張頁表,用來記錄虛擬記憶體與實體記憶體的對映關係

 

如果程式要訪問的虛擬記憶體沒有被分配實體記憶體(即在頁表中找不到對映關係),就會產生一個缺頁異常中斷

 

這時候系統會進入核心空間分配實體記憶體、然後更新程式頁表,最後再返回使用者空間,恢復程式的執行

 

 


感謝閱讀,喜歡作者就動動小手[一鍵三連],這是我寫作最大的動力

 

相關文章