哈嘍大家好,我是鹹魚
今天我們來學習一下 Linux 作業系統核心之一:記憶體
跟 CPU 一樣,記憶體也是作業系統最核心的功能之一,記憶體主要用來儲存系統和程式的指令、資料、快取等
關於記憶體的學習,我會盡量以通俗易懂的方式且分成多篇文章去講解
那麼今天在 pt.1 文章中,我們來學習一下 Linux 中的虛擬記憶體、實體記憶體和記憶體對映
只有核心才可以直接存取實體記憶體,程序是無法直接存取實體記憶體的
那麼程序是如何存取實體記憶體?
Linux 核心給每個程序都提供了一個獨立的虛擬地址空間,並且這個空間是連續的,這樣程序就可以很方便的存取到記憶體,準確來說是存取到虛擬記憶體
又因為這個虛擬地址空間(虛擬記憶體)與實體記憶體相關聯,程序則是通過虛擬記憶體去存取實體記憶體的
虛擬地址空間又被分成核心空間和使用者空間,程序在使用者態時只能存取虛擬使用者空間地址,在核心態可以存取虛擬核心空間地址
對於不同位數位長(單個 CPU 指令可以處理資料的最大長度)的處理器(32位元系統、64位元系統),地址空間的範圍也不同
由上圖可以看到,32 位系統的核心空間佔 1G,位於最高處;剩下的 3G 是使用者空間
而 64 位系統的核心空間和使用者空間都是 128T,分別佔據整個記憶體空間的最高和最低處,剩下的中間部分是未定義的
雖然每個程序都有虛擬核心空間,但每個程序的虛擬核心空間記憶體關聯的都是相同的實體記憶體,方便程序切換到核心態後去存取實體記憶體
實體地址空間是實體記憶體的範圍,虛擬地址空間是虛擬記憶體的範圍,實體地址空間中的每個實體地址都是實打實地指向了具體的儲存單元
虛擬地址空間中每個虛擬地址指向哪裡有 3 種情況:
未分配,這個虛擬地址僅僅是個數位而已,沒有任何指向
未緩衝,這個虛擬地址指向了磁碟的某個位元組儲存單元,裡面儲存了指令或者資料
已緩衝,這個虛擬地址指向了實體記憶體的某個位元組儲存單元,裡面儲存了指令或者資料。
虛擬記憶體的好處:
避免使用者直接存取實體記憶體,防止一些破壞性操作,保護作業系統
每個程序都被分配了 4GB 的 虛擬地址空間,使用者可使用比實力實體記憶體更大的地址空間(用的時候才分配)
那麼當程序實際使用的時候,程序的虛擬記憶體是怎麼分配到實體記憶體的呢?
並不是所有的虛擬記憶體都會被分配實體記憶體,只有那些實際使用的虛擬記憶體才分配實體記憶體,並且分配後的實體記憶體,是通過記憶體對映來管理的
記憶體對映,其實就是將虛擬記憶體地址對映到實體記憶體地址
為了完成記憶體對映,核心為每個程序都維護了一張頁表,用來記錄虛擬記憶體與實體記憶體的對映關係
頁表實際上儲存在 CPU 的記憶體管理單元 MMU 中。這樣,正常情況下,CPU 就可以直接通過硬體,找出要存取的記憶體
這張頁表裡面有很多頁表項,每個頁表項的大小為 4KB。當程序存取的虛擬記憶體被分配了實體記憶體之後,系統就會更新頁表,在頁表項中新增虛擬記憶體與實體記憶體的對映關係
缺頁異常
如果程序要存取的虛擬記憶體沒有被分配實體記憶體(即在頁表中找不到對映關係),就會產生一個缺頁異常中斷
這時候系統會進入核心空間分配實體記憶體、然後更新程序頁表,最後再返回使用者空間,恢復程序的執行
MMU 中有一個快取記憶體 TLB((Translation Lookaside Buffer,轉譯後備緩衝器),TLB 存取速度要比 MMU 快得多
通過提高 TLB 快取使用率,可以提高 CPU 的記憶體存取效能
在 Linux 中,為了提高記憶體利用率和系統可靠性,同時也為了不同程序之間的記憶體隔離,程序不能直接存取到實體記憶體
Linux 為每一個程序都分配了一個虛擬記憶體,當程序實際使用的時候,虛擬記憶體才會被分配實體記憶體
Linux 通過記憶體對映的方式來實現通過虛擬記憶體去存取實體記憶體,為了完成記憶體對映,核心為每個程序都維護了一張頁表,用來記錄虛擬記憶體與實體記憶體的對映關係
如果程序要存取的虛擬記憶體沒有被分配實體記憶體(即在頁表中找不到對映關係),就會產生一個缺頁異常中斷
這時候系統會進入核心空間分配實體記憶體、然後更新程序頁表,最後再返回使用者空間,恢復程序的執行
感謝閱讀,喜歡作者就動動小手[一鍵三連],這是我寫作最大的動力