哈嘍大家好,我是鹹魚 今天我們來學習一下 Linux 操作系統核心之一:記憶體 跟 CPU 一樣,記憶體也是操作系統最核心的功能之一,記憶體主要用來存儲系統和程式的指令、數據、緩存等 關於記憶體的學習,我會儘量以通俗易懂的方式且分成多篇文章去講解 那麼今天在 pt.1 文章中,我們來學習一下 Linux 中 ...
哈嘍大家好,我是鹹魚
今天我們來學習一下 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 通過記憶體映射的方式來實現通過虛擬記憶體去訪問物理記憶體,為了完成記憶體映射,內核為每個進程都維護了一張頁表,用來記錄虛擬記憶體與物理記憶體的映射關係
如果進程要訪問的虛擬記憶體沒有被分配物理記憶體(即在頁表中找不到映射關係),就會產生一個缺頁異常中斷
這時候系統會進入內核空間分配物理記憶體、然後更新進程頁表,最後再返回用戶空間,恢復進程的運行
感謝閱讀,喜歡作者就動動小手[一鍵三連],這是我寫作最大的動力