日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux内存描述之概述--Linux内存管理(一)

發(fā)布時(shí)間:2025/4/16 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内存描述之概述--Linux内存管理(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1 前景回顧

1.1 UMA和NUMA兩種模型

共享存儲(chǔ)型多處理機(jī)有兩種模型

  • 均勻存儲(chǔ)器存取(Uniform-Memory-Access,簡稱UMA)模型

將可用內(nèi)存以連續(xù)方式組織起來,

  • 非均勻存儲(chǔ)器存取(Nonuniform-Memory-Access,簡稱NUMA)模型

1.2 UMA模型

傳統(tǒng)的多核運(yùn)算是使用SMP(Symmetric Multi-Processor )模式:將多個(gè)處理器與一個(gè)集中的存儲(chǔ)器和I/O總線相連。所有處理器只能訪問同一個(gè)物理存儲(chǔ)器,因此SMP系統(tǒng)有時(shí)也被稱為一致存儲(chǔ)器訪問(UMA)結(jié)構(gòu)體系,一致性意指無論在什么時(shí)候,處理器只能為內(nèi)存的每個(gè)數(shù)據(jù)保持或共享唯一一個(gè)數(shù)值。

物理存儲(chǔ)器被所有處理機(jī)均勻共享。所有處理機(jī)對所有存儲(chǔ)字具有相同的存取時(shí)間,這就是為什么稱它為均勻存儲(chǔ)器存取的原因。每臺(tái)處理機(jī)可以有私用高速緩存,外圍設(shè)備也以一定形式共享。

很顯然,SMP的缺點(diǎn)是可伸縮性有限,因?yàn)樵诖鎯?chǔ)器和I/O接口達(dá)到飽和的時(shí)候,增加處理器并不能獲得更高的性能,與之相對應(yīng)的有AMP架構(gòu),不同核之間有主從關(guān)系,如一個(gè)核控制另外一個(gè)核的業(yè)務(wù),可以理解為多核系統(tǒng)中控制平面和數(shù)據(jù)平面。

1.3 NUMA模型

NUMA模式是一種分布式存儲(chǔ)器訪問方式,處理器可以同時(shí)訪問不同的存儲(chǔ)器地址,大幅度提高并行性。 NUMA總是多處理器計(jì)算機(jī),系統(tǒng)的哪個(gè)CPU都有本地內(nèi)存, 可支持快速的訪問, 各個(gè)處理器之前通過總線鏈接起來, 以支持堆其他CPU的本地內(nèi)存的訪問, 當(dāng)然訪問要比本地內(nèi)存慢.

NUMA模式下,處理器被劃分成多個(gè)”節(jié)點(diǎn)”(node), 每個(gè)節(jié)點(diǎn)被分配有的本地存儲(chǔ)器空間。 所有節(jié)點(diǎn)中的處理器都可以訪問全部的系統(tǒng)物理存儲(chǔ)器,但是訪問本節(jié)點(diǎn)內(nèi)的存儲(chǔ)器所需要的時(shí)間,比訪問某些遠(yuǎn)程節(jié)點(diǎn)內(nèi)的存儲(chǔ)器所花的時(shí)間要少得多。

其訪問時(shí)間隨存儲(chǔ)字的位置不同而變化。其共享存儲(chǔ)器物理上是分布在所有處理機(jī)的本地存儲(chǔ)器上。所有本地存儲(chǔ)器的集合組成了全局地址空間,可被所有的處理機(jī)訪問。處理機(jī)訪問本地存儲(chǔ)器是比較快的,但訪問屬于另一臺(tái)處理機(jī)的遠(yuǎn)程存儲(chǔ)器則比較慢,因?yàn)橥ㄟ^互連網(wǎng)絡(luò)會(huì)產(chǎn)生附加時(shí)延

NUMA 的主要優(yōu)點(diǎn)是伸縮性。NUMA 體系結(jié)構(gòu)在設(shè)計(jì)上已超越了 SMP 體系結(jié)構(gòu)在伸縮性上的限制。通過 SMP,所有的內(nèi)存訪問都傳遞到相同的共享內(nèi)存總線。這種方式非常適用于 CPU 數(shù)量相對較少的情況,但不適用于具有幾十個(gè)甚至幾百個(gè) CPU 的情況,因?yàn)檫@些 CPU 會(huì)相互競爭對共享內(nèi)存總線的訪問。NUMA 通過限制任何一條內(nèi)存總線上的 CPU 數(shù)量并依靠高速互連來連接各個(gè)節(jié)點(diǎn),從而緩解了這些瓶頸狀況。

2 (N)UMA模型中l(wèi)inux內(nèi)存的機(jī)構(gòu)

Linux適用于各種不同的體系結(jié)構(gòu), 而不同體系結(jié)構(gòu)在內(nèi)存管理方面的差別很大. 因此linux內(nèi)核需要用一種體系結(jié)構(gòu)無關(guān)的方式來表示內(nèi)存.

Linux內(nèi)核通過插入一些兼容層, 使得不同體系結(jié)構(gòu)的差異很好的被隱藏起來, 內(nèi)核對一致和非一致內(nèi)存訪問使用相同的數(shù)據(jù)結(jié)構(gòu)

2.1 (N)UMA模型中l(wèi)inux內(nèi)存的機(jī)構(gòu)

非一致存儲(chǔ)器訪問(NUMA)模式下

  • 處理器被劃分成多個(gè)”節(jié)點(diǎn)”(node), 每個(gè)節(jié)點(diǎn)被分配有的本地存儲(chǔ)器空間. 所有節(jié)點(diǎn)中的處理器都可以訪問全部的系統(tǒng)物理存儲(chǔ)器,但是訪問本節(jié)點(diǎn)內(nèi)的存儲(chǔ)器所需要的時(shí)間,比訪問某些遠(yuǎn)程節(jié)點(diǎn)內(nèi)的存儲(chǔ)器所花的時(shí)間要少得多
  • 內(nèi)存被分割成多個(gè)區(qū)域(BANK,也叫”簇”),依據(jù)簇與處理器的”距離”不同, 訪問不同簇的代碼也會(huì)不同. 比如,可能把內(nèi)存的一個(gè)簇指派給每個(gè)處理器,或則某個(gè)簇和設(shè)備卡很近,很適合DMA,那么就指派給該設(shè)備。因此當(dāng)前的多數(shù)系統(tǒng)會(huì)把內(nèi)存系統(tǒng)分割成2塊區(qū)域,一塊是專門給CPU去訪問,一塊是給外圍設(shè)備板卡的DMA去訪問

在UMA系統(tǒng)中, 內(nèi)存就相當(dāng)于一個(gè)只使用一個(gè)NUMA節(jié)點(diǎn)來管理整個(gè)系統(tǒng)的內(nèi)存. 而內(nèi)存管理的其他地方則認(rèn)為他們就是在處理一個(gè)(偽)NUMA系統(tǒng).

2.2 Linux物理內(nèi)存的組織形式

Linux把物理內(nèi)存劃分為三個(gè)層次來管理

層次描述
存儲(chǔ)節(jié)點(diǎn)(Node)CPU被劃分為多個(gè)節(jié)點(diǎn)(node), 內(nèi)存則被分簇, 每個(gè)CPU對應(yīng)一個(gè)本地物理內(nèi)存, 即一個(gè)CPU-node對應(yīng)一個(gè)內(nèi)存簇bank,即每個(gè)內(nèi)存簇被認(rèn)為是一個(gè)節(jié)點(diǎn)
管理區(qū)(Zone)每個(gè)物理內(nèi)存節(jié)點(diǎn)node被劃分為多個(gè)內(nèi)存管理區(qū)域, 用于表示不同范圍的內(nèi)存, 內(nèi)核可以使用不同的映射方式映射物理內(nèi)存
頁面(Page)內(nèi)存被細(xì)分為多個(gè)頁面幀, 頁面是最基本的頁面分配的單位

為了支持NUMA模型,也即CPU對不同內(nèi)存單元的訪問時(shí)間可能不同,此時(shí)系統(tǒng)的物理內(nèi)存被劃分為幾個(gè)節(jié)點(diǎn)(node), 一個(gè)node對應(yīng)一個(gè)內(nèi)存簇bank,即每個(gè)內(nèi)存簇被認(rèn)為是一個(gè)節(jié)點(diǎn)

  • 首先, 內(nèi)存被劃分為結(jié)點(diǎn). 每個(gè)節(jié)點(diǎn)關(guān)聯(lián)到系統(tǒng)中的一個(gè)處理器, 內(nèi)核中表示為pg_data_t的實(shí)例. 系統(tǒng)中每個(gè)節(jié)點(diǎn)被鏈接到一個(gè)以NULL結(jié)尾的pgdat_list鏈表中<而其中的每個(gè)節(jié)點(diǎn)利用pg_data_tnode_next字段鏈接到下一節(jié).而對于PC這種UMA結(jié)構(gòu)的機(jī)器來說, 只使用了一個(gè)成為contig_page_data的靜態(tài)pg_data_t結(jié)構(gòu).
  • 接著各個(gè)節(jié)點(diǎn)又被劃分為內(nèi)存管理區(qū)域, 一個(gè)管理區(qū)域通過struct zone_struct描述, 其被定義為zone_t, 用以表示內(nèi)存的某個(gè)范圍, 低端范圍的16MB被描述為ZONE_DMA, 某些工業(yè)標(biāo)準(zhǔn)體系結(jié)構(gòu)中的(ISA)設(shè)備需要用到它, 然后是可直接映射到內(nèi)核的普通內(nèi)存域ZONE_NORMAL,最后是超出了內(nèi)核段的物理地址域ZONE_HIGHMEM, 被稱為高端內(nèi)存. 是系統(tǒng)中預(yù)留的可用內(nèi)存空間, 不能被內(nèi)核直接映射.
  • 最后頁幀(page frame)代表了系統(tǒng)內(nèi)存的最小單位, 堆內(nèi)存中的每個(gè)頁都會(huì)創(chuàng)建一個(gè)struct page的一個(gè)實(shí)例. 傳統(tǒng)上,把內(nèi)存視為連續(xù)的字節(jié),即內(nèi)存為字節(jié)數(shù)組,內(nèi)存單元的編號(地址)可作為字節(jié)數(shù)組的索引. 分頁管理時(shí),將若干字節(jié)視為一頁,比如4K byte. 此時(shí),內(nèi)存變成了連續(xù)的頁,即內(nèi)存為頁數(shù)組,每一頁物理內(nèi)存叫頁幀,以頁為單位對內(nèi)存進(jìn)行編號,該編號可作為頁數(shù)組的索引,又稱為頁幀號.

在一個(gè)單獨(dú)的節(jié)點(diǎn)內(nèi),任一給定CPU訪問頁面所需的時(shí)間都是相同的。然而,對不同的CPU,這個(gè)時(shí)間可能就不同。對每個(gè)CPU而言,內(nèi)核都試圖把耗時(shí)節(jié)點(diǎn)的訪問次數(shù)減到最少這就要小心地選擇CPU最常引用的內(nèi)核數(shù)據(jù)結(jié)構(gòu)的存放位置.

2.3 內(nèi)存節(jié)點(diǎn)node

CPU被劃分為多個(gè)節(jié)點(diǎn)(node), 內(nèi)存則被分簇, 每個(gè)CPU對應(yīng)一個(gè)本地物理內(nèi)存, 即一個(gè)CPU-node對應(yīng)一個(gè)內(nèi)存簇bank,即每個(gè)內(nèi)存簇被認(rèn)為是一個(gè)節(jié)點(diǎn)

系統(tǒng)的物理內(nèi)存被劃分為幾個(gè)節(jié)點(diǎn)(node), 一個(gè)node對應(yīng)一個(gè)內(nèi)存簇bank,即每個(gè)內(nèi)存簇被認(rèn)為是一個(gè)節(jié)點(diǎn)

在LINUX中引入一個(gè)數(shù)據(jù)結(jié)構(gòu)struct pglist_data ,來描述一個(gè)node,定義在include/linux/mmzone.h 文件中。(這個(gè)結(jié)構(gòu)被typedef pg_data_t)。

  • 對于NUMA系統(tǒng)來講, 整個(gè)系統(tǒng)的內(nèi)存由一個(gè)node_data的pg_data_t指針數(shù)組來管理,
  • 對于PC這樣的UMA系統(tǒng),使用struct pglist_data contig_page_data ,作為系統(tǒng)唯一的node管理所有的內(nèi)存區(qū)域。(UMA系統(tǒng)中中只有一個(gè)node)

可以使用NODE_DATA(node_id)來查找系統(tǒng)中編號為node_id的結(jié)點(diǎn), 參見NODE_DATA的定義

UMA結(jié)構(gòu)下由于只有一個(gè)結(jié)點(diǎn), 因此該宏總是返回全局的contig_page_data, 而與參數(shù)node_id無關(guān).

extern struct pglist_data *node_data[]; #define NODE_DATA(nid) (node_data[(nid)])

在UMA結(jié)構(gòu)的機(jī)器中, 只有一個(gè)node結(jié)點(diǎn)即contig_page_data, 此時(shí)NODE_DATA直接指向了全局的contig_page_data, 而與node的編號nid無關(guān), 參照include/linux/mmzone.h?v=4.7, line 858, 其中全局唯一的內(nèi)存node結(jié)點(diǎn)contig_page_data定義在mm/nobootmem.c?v=4.7, line 27, linux-2.4.37

#ifndef CONFIG_NEED_MULTIPLE_NODES extern struct pglist_data contig_page_data; #define NODE_DATA(nid) (&contig_page_data) #define NODE_MEM_MAP(nid) mem_map else /* ...... */ #endif

在分配一個(gè)頁面時(shí), Linux采用節(jié)點(diǎn)局部分配的策略, 從最靠近運(yùn)行中的CPU的節(jié)點(diǎn)分配內(nèi)存, 由于進(jìn)程往往是在同一個(gè)CPU上運(yùn)行, 因此從當(dāng)前節(jié)點(diǎn)得到的內(nèi)存很可能被用到

2.4 物理內(nèi)存區(qū)域zone

因?yàn)閷?shí)際的計(jì)算機(jī)體系結(jié)構(gòu)有硬件的諸多限制, 這限制了頁框可以使用的方式. 尤其是, Linux內(nèi)核必須處理80x86體系結(jié)構(gòu)的兩種硬件約束.

  • ISA總線的直接內(nèi)存存儲(chǔ)DMA處理器有一個(gè)嚴(yán)格的限制 : 他們只能對RAM的前16MB進(jìn)行尋址
  • 在具有大容量RAM的現(xiàn)代32位計(jì)算機(jī)中, CPU不能直接訪問所有的物理地址, 因?yàn)榫€性地址空間太小, 內(nèi)核不可能直接映射所有物理內(nèi)存到線性地址空間, 我們會(huì)在后面典型架構(gòu)(x86)上內(nèi)存區(qū)域劃分詳細(xì)講解x86_32上的內(nèi)存區(qū)域劃分

因此Linux內(nèi)核對不同區(qū)域的內(nèi)存需要采用不同的管理方式和映射方式,

為了解決這些制約條件,Linux使用了三種區(qū):

  • ZONE_DMA : 這個(gè)區(qū)包含的頁用來執(zhí)行DMA操作。
  • ZONE_NOMAL : 這個(gè)區(qū)包含的都是能正常映射的頁。
  • ZONE_HIGHEM : 這個(gè)區(qū)包”高端內(nèi)存”,其中的頁能不永久地映射到內(nèi)核地址空間
  • 而為了兼容一些設(shè)備的熱插拔支持以及內(nèi)存碎片化的處理, 內(nèi)核也引入一些邏輯上的內(nèi)存區(qū).

    內(nèi)核將每個(gè)簇所對應(yīng)的node又被分成的稱為管理區(qū)(zone)的塊,它們各自描述在內(nèi)存中的范圍。一個(gè)管理區(qū)(zone)由struct zone結(jié)構(gòu)體來描述,在linux-2.4.37之前的內(nèi)核中是用typedef struct zone_struct zone_t數(shù)據(jù)結(jié)構(gòu)來描述)

    對于x86_32的機(jī)器,管理區(qū)(內(nèi)存區(qū)域)類型如下分布

    類型區(qū)域
    ZONE_DMA0~15MB
    ZONE_NORMAL16MB~895MB
    ZONE_HIGHMEM896MB~物理內(nèi)存結(jié)束

    內(nèi)核在初始化內(nèi)存管理區(qū)時(shí), 首先建立管理區(qū)表zone_table. 參見mm/page_alloc.c?v=2.4.37, line 38

    /*** The zone_table array is used to look up the address of the* struct zone corresponding to a given zone number (ZONE_DMA,* ZONE_NORMAL, or ZONE_HIGHMEM).*/ zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES]; EXPORT_SYMBOL(zone_table);

    該表處理起來就像一個(gè)多維數(shù)組,

    • MAX_NR_ZONES是一個(gè)節(jié)點(diǎn)中所能包容納的管理區(qū)的最大數(shù), 如3個(gè), 定義在include/linux/mmzone.h?v=2.4.37, line 25, 與zone區(qū)域的類型(ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM)定義在一起. 當(dāng)然這時(shí)候我們這些標(biāo)識都是通過宏的方式來實(shí)現(xiàn)的, 而不是如今的枚舉類型
    • MAX_NR_NODES是可以存在的節(jié)點(diǎn)的最大數(shù).
    • 函數(shù)EXPORT_SYMBOL使得內(nèi)核的變量或者函數(shù)可以被載入的模塊(比如我們的驅(qū)動(dòng)模塊)所訪問.

    2.5 內(nèi)存頁page

    大多數(shù)內(nèi)核(kernel)的操作只使用ZONE_NORMAL區(qū)域,系統(tǒng)內(nèi)存由很多固定大小的內(nèi)存塊組成的,這樣的內(nèi)存塊稱作為“頁”(PAGE),

    x86體系結(jié)構(gòu)中,page的大小為4096個(gè)字節(jié)。

    每個(gè)物理的頁由一個(gè)struct page的數(shù)據(jù)結(jié)構(gòu)對象來描述。頁的數(shù)據(jù)結(jié)構(gòu)對象都保存在mem_map全局?jǐn)?shù)組中,該數(shù)組通常被存放在ZONE_NORMAL的首部,或者就在小內(nèi)存系統(tǒng)中為裝入內(nèi)核映像而預(yù)留的區(qū)域之后。從載入內(nèi)核的低地址內(nèi)存區(qū)域的后面內(nèi)存區(qū)域,也就是ZONE_NORMAL開始的地方的內(nèi)存的頁的數(shù)據(jù)結(jié)構(gòu)對象,都保存在這個(gè)全局?jǐn)?shù)組中。

    2.6 高端內(nèi)存

    由于能夠被Linux內(nèi)核直接訪問的ZONE_NORMAL區(qū)域的內(nèi)存空間也是有限的,所以LINUX提出了高端內(nèi)存(High memory)的概念,并且允許對高端內(nèi)存的訪問

    轉(zhuǎn)載于:https://www.cnblogs.com/linhaostudy/p/9986692.html

    總結(jié)

    以上是生活随笔為你收集整理的Linux内存描述之概述--Linux内存管理(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。