Linux記憶體管理之二 記憶體節點和記憶體分割槽

2021-09-14 02:43:14 字數 1767 閱讀 5472

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分配。

Linux記憶體管理系列之二 物理記憶體分配機制

記憶體是計算機的重要組成部分,它是一種物理介質,它的訪問速度介於cpu與磁碟之間。它的主要作用是用來交換資料,即將磁碟組的資料通過記憶體讀入cpu,同時將cpu操作後的資料通過記憶體寫入磁碟。在當下的linux中,記憶體主要包括 核心空間記憶體與使用者空間記憶體。這兩部分的記憶體全部由linux核心...

Linux記憶體管理 二

記憶體的分配與 在程式中申請堆上的記憶體使用 malloc函式,在系統呼叫中可以呼叫 brk 函式 和 mmap 函式 當申請的記憶體小於128kb 預設值 的時候會呼叫brk 函式在heap上開闢記憶體,當申請記憶體大於等於128kb 預設值 的時候會呼叫mmap 函式在mmap對映區開闢記憶體 ...

記憶體管理二

發現兩篇記憶體池的博文,博文位址如下,寫的很好,能避免記憶體碎片和記憶體洩露問題,比我這個玩具 要好很多,大家可以看看 在我們做專案的時候,經常會分配了記憶體,然後卻忘了釋放,造成記憶體洩漏的問題。以下 可以實現在 退出的時候自動釋放之前申請但未釋放的記憶體。其原理是 用乙個雙向鍊錶維護申請的記憶體...