Linux內存管理之二 內存節點和內存分區

UMA和NUMA:
UMA(Uniform Memory Access),即一致性內存訪問。這種情況下,CPU訪問內存的任何位置,代價都是一樣的。
NUMA)(Non Uniform Memory Access),即非一致性內存訪問。這種情況下,CPU訪問不同位置的內存,代價是不一樣的。在多CPU情況下,對每個CPU來說有本地內存和遠端內存,訪問本地內存的代價比訪問遠端內存的代價小。確保CPU訪問內存代價最小,是非常重要的一點。

Linux支持多種硬件體系結構,因此Linux必須採用通用的方法來描述內存,以方便對內存進行管理。爲此,Linux有了內存節點、內存區、頁框的概念,這些概念也是一目瞭然的。
內存節點:主要依據CPU訪問代價的不同而劃分。多CPU下環境下,本地內存和遠端內存就是不同的節點。即使在單CPU環境下,訪問所有內存的代價都是一樣的,Linux內核依然存在內存節點的概念,只不過只有一個內存節點而已。內核以struct  pg_data_t來描述內存分區。
內存分區:Linux對內存節點再進行劃分,分爲不同的分區。內核以struct zone來描述內存分區。通常一個節點分爲DMA、Normal和High Memory內存區,具體下面再介紹。

頁框:Linux採用頁式內存管理,頁是物理內存管理的基本單位,每個內存分區又由大量的頁框組成。內核以struct page來描述頁框。頁框有很多屬性,這些屬性描述了這個頁框的狀態、用途等,例如是否被分配。


上圖中的zone_mem_map是一個頁框的數組,它記錄了一個內存分區的所有頁框的使用情況。


DMA內存區:即直接內存訪問分區,通常爲物理內存的起始16M。主要是供一些外設使用,外設和內存直接訪問數據訪問,而無需系統CPU的參與。
Normal內存區:從16M到896M內存區。
HighMemory內存區:896M以後的內存區。

爲什麼高端內存的邊界是896M?這是因爲,32位Linux虛擬內存空間爲0-4G,其中0-3G用於用戶態,3G-4G用於內核態。這意味着內核只有1G的虛擬地址空間,如果物理內存超過1G,內核就無法映射了。Linux採取的策略是,內核地址空間的前896M採用固定映射,映射方法是:虛擬地址-3G = 物理地址,只能映射到物理地址的前896M。也就是說內核虛擬地址空間的3G到3G+896M這部分,頁表的映射是固定的,系統初始化時就建立起來。而虛擬地址空間的最後128M,也就是3G+896M到4G部分採用動態映射,也就是說頁表映射的物理地址可變的。在系統運行過程中,通過更新頁表,就可以映射到不同的物理地址,當然也包括高端物理內存。

這主要解決了兩個問題:第一,這可以使內核地址空間映射到高端物理內存;第二,虛擬地址空間的3G+896M到4G部分,連續的虛擬地址空間可以映射到非連續的物理內存,只要通過更新頁表就可以做到,這和用戶態的虛擬內存映射採用了同樣這種方法。這在沒有大段連續的空閒物理地址時,是非常重要的。

備用內存區:
在一個內存區分配頁時,如果這個內存區沒有滿足條件的內存頁,則需要從其它內存區或從其它內存節點分配。Linux爲每個內存區都建立了備用內存區列表,當前內存區沒有滿足條件的內存時,就從備用內存區分配。比如,系統中有4個內存節點A,B,C,D,每個內存節點又分爲DMA、Normal、HighMemory內存區。對節點B來說,內存區分配列表可能是B(HighMemory)、B(Normal)、B(DMA)、
A(HighMemory)、A(Normal)、A(DMA)、
C(HighMemory)、C(Normal)、C(DMA)、
D(HighMemory)、D(Normal)、D(DMA)。
分配內存時,優先從本地內存節點分配,再從其它內存節點分配。對一個內存節點,優先從HighMemory分配,再從Normal或DMA分配
發佈了65 篇原創文章 · 獲贊 58 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章