Linux內存,先看這篇文章

內存大小計算

我們拿32位系統來舉個栗子

2^32 = ‭4,294,967,296‬ bytes

‭4,294,967,296‬ bytes / 1024 = ‭4,194,304‬ kbytes

4,194,304‬ kbytes / 1024= ‭4,096‬ M

‭4,096‬ M /1024 =  4G

物理內存如何分頁?

分段和分頁計算機內存管理的兩種方式,這裏我只討論分頁。

比如是 4G的內存,我們一個頁的大小是 4K,那可以分成多少個頁呢?

通過一系列複雜而且不爲人知的計算

4,194,304‬ kbytes / 4 = ‭1,048,576

所以分頁後的物理內存應該是這樣排列的

MMU是什麼?

如果操作系統是一家銀行,那MMU就是這家銀行的資金倉庫管理員,所有要申請資金的人都要通過管理員才能拿到錢。

我們說的MMU就是內存管理單元,所有什麼亂七八糟的虛擬地址最後都是都需要經過MMU這個內存管家把虛擬地址轉換成物理地址來操作的。

順便說一句,並不是所有的支票都可以轉成錢的,有些也可能是空頭支票,操作系統給應用的虛擬內存,這些虛擬內存並不是都能轉換成相對應的物理內存的

分頁模式下的虛擬地址轉換成物理地址對應圖

上面分頁的問題

如果是32的系統,我們4G的內存,分成4KB一個頁,那需要多少個頁呢?

4,194,304‬ kbytes / 4 = ‭1,048,576‬

我們上面已經計算出來了,如果一個虛擬地址和物理地址的映射關係需要4個字節來存儲,那我們需要多少空間呢?

1,048,576‬  x 4bytes = ‭4,194,304‬ bytes /1024 = ‭4,096‬ k / 1024 = 4M

就是說我們一個映射關係需要 4M的內存,我們操作系統開一個進程就需要開一個映射表,如果我我們開100個進程就需要400M內存,這樣的話,我們的操作系統的內存會非常非常喫緊。

所以,操作系統的開發大牛們就發明了多級頁表這個東西,多級頁表的作用就是爲了省空間,每當讀到這裏,我每每感嘆,自己比別人是笨了多少個等級啊。

爲什麼需要4個字節來存一個頁表項呢?因爲是32爲地址,一個字節是8位,4個字節剛好是32位,所以就需要4個字節存儲頁表項。

有人會問,這4K存的是物理地址還是虛擬地址呢?

大家想一下,物理地址的分頁在系統啓動的時候已經確定好了,物理地址是沒有必要分多次的。所以這個存的是虛擬地址。

多級頁表

然後,大神們就設計出這樣的分頁方式

多級頁表劃分

我們上面說了,如果只用一級分頁的話,導致一個問題是需要的太多的空間來存儲映射關係了,那現在改成使用32bit不同的bit來尋址,需要多少內存來存儲呢?

2^10 = 1024bytes = 1k

一個頁表大小是 4 K ,我們是一個字節一個字節的偏移的,所以一個頁我們一定需要 12個bit做偏移來獲取頁中的具體位置,所以我們必須要留12bits給頁表偏移使用。

既然頁表偏移使用12bit,那頁目錄和頁表各分到10bits。

1024 * 1024 = ‬ ‭1,048,576‬

1,048,576‬  x 4 k = ‭4,194,304‬ k

‭4,194,304‬ k / 1024 = 4096M = 4G

這樣分是不是很牛,計算出來就剛剛好等於 4G 內存

那頁表項我們需要多少內存空間呢?

頁目錄一共是 2^10 = 1024 項,每一項代表一個頁目錄表的編號,一個頁目錄表我們需要4個字節來表示,所以佔用的存儲空間應該是 1024 * 4bytes = 4K 大小。

同理頁表也是一樣,需要4K大小的存儲空間

偏移量這個是不需要存儲的,我們只要知道了前面兩個位置,再加上偏移量,就能準確知道內存的具體位置了

我們把這種分段方式想象成一本書,就很好理解了。比如,我們要在新華字典查某個字的時候,我們需要在目錄裏面找這個字在哪一頁,這個就需要一個頁目錄表。然後,我們找到確定的頁數後,再通過頁表找到在哪一行。最後,我們通過偏移量找到這個字跟行首偏移多少個字。

我們這樣就能找到確定的字了。

如下圖

推薦閱讀:

專輯|Linux文章彙總

專輯|程序人生

end

嵌入式Linux

微信掃描二維碼,關注我的公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章