這兩天在研究內核下關於內存信息的獲取,發現proc文件下有一個pagetypeinfo,通過查看該文件,可以看到以下內容:
Page block order: 9
Pages per block: 512
Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
Node 0, zone DMA, type Unmovable 0 1 0 1 1 1 1 0 1 0 0
Node 0, zone DMA, type Movable 0 0 0 0 0 0 0 0 0 1 3
Node 0, zone DMA, type Reclaimable 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Unmovable 40 22 4 15 7 2 0 0 1 1 1
Node 0, zone DMA32, type Movable 2674 2438 1697 1214 594 143 27 4 4 1 476
Node 0, zone DMA32, type Reclaimable 30 36 18 9 11 9 17 13 5 3 4
Node 0, zone DMA32, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Unmovable 126 32 17 5 7 0 0 0 0 0 0
Node 0, zone Normal, type Movable 49 11390 4915 618 279 4 0 0 0 0 0
Node 0, zone Normal, type Reclaimable 127 78 253 99 75 9 1 0 0 0 0
Node 0, zone Normal, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Number of blocks type Unmovable Movable Reclaimable HighAtomic Isolate
Node 0, zone DMA 1 7 0 0 0
Node 0, zone DMA32 6 1754 24 0 0
Node 0, zone Normal 221 1724 343 0 0
先大概分析一下,可以看到我的內存被分成了0-9個order,每一塊512。我的內存通過free -k看到的是7862296K大,也就是7.4G(這確實應該是我機器的實際內存)。512*10跟7.4G也沒有什麼關係啊。這個先放放,現在想一下DMA,DMA32,Normal都是什麼意思吧,還有這些數字都要表示什麼。
於是找到了這一篇文章How the Linux kernel divides up your RAM,現在翻譯如下:
linux內核並不將你的所有物理內存都當作一個巨大的無區別的內存池。而是,它將其劃分爲多個區域(至少是爲了滿足內核的需求),這些區域被稱作zone。是什麼樣的內存區域取決於你的機器是32位還是64位,或者是更加複雜的一些設計。
這些zones就包括:
- DMA:這是低16M字節的內存,它的存在是因爲歷史原因:因爲以前的一些硬件設備,只能通過DMA進行索引,也就是說一些硬件設備的地址需要綁在DMA上。
- DMA32:他們只存在於64位的linux機器上,這是內存的低4G區域,可能會更多點也可能更少點。它的存在同樣是爲那些地址只能映射到低4g範圍的硬件資源考慮。(這就是人們抱怨這又是舊事物又是新事物的地方)
- Normal在32位機器和64位機器上是不一樣的。在64位機器上,這裏的內存僅僅是4GB或者是4GB再往上的地址空間,在32位的機器上,只有16MB到896M的地方是Normal區域(PS:在之前看深入理解linux內存管理的時候,好像說過這部分內存,這部分內存是內核獨有的)。這個區域仍然是出於一些歷史原因的考慮
這裏注意在64位機器上,Normal區域的相當小,除非有着大於4g的物理空間。舉個例子,一個2G的機器跑着64位的內核將不會有Normal區域的內存,4G的機器會有一點點Normal區域的內存 - HighMem只在32位linux上存在,它是說高於896M的內存區域,包括內存大於4G這樣資源充足的機器上。
一般情況下,內存分配可能在一個資源相關受限的區域。比如說你申請Normal區域的memory在64位的機器上,那裏幾乎沒有Normal內存,倒是有不少DMA32,你會得到DMA32的內存。這只是內核更加傾向於保留DMA32來處理一些特定的申請請求。
現在,事情其實簡單了起來,一般情況下,zones和內存都會被關聯到一個叫做node
的東西上。一般的機器只有一個node->node0
,不過資源充分的服務器會有很多node(我們有一臺機器有8個node)。Node是現在linux提出NUMA架構(非統一內存獲取,與CPU相關聯的設計)的體現。簡單來說,每一個CPU都會關聯一個node,內核會將node上的內存優先分配給這個cpu上的進程,因爲‘近’。
我相信這些特殊的zones(DMA,DMA32,Normal)目前只在一個node上,也就是node0。所有的其他node只會包含Normal(64位機器),或者是HighMem(32位機器)的內存。
你可以看到大量的信息關於系統的nodes
,zones
。他們的狀態可以在**/proc/pagetypeinfo**,/proc/zoneinfo,/proc/<pid>/numa_maps,還有**/proc/buddyinfo**中看到。這些信息都值得有一個詳盡的解釋。
內核的內存分配單元就是4k的頁(很多數據的報告也就是報告頁的數量,而不是用K字節表示多少內存剩下)。內核也會跟蹤着巨大連續頁內存的信息,因爲有的時候內核想要大量連續的內存頁。/proc/buddyinfo想你展示了有多少塊的內存信息,並按照 order
進行排序,order
就是2order次冪的大小頁,order0也就是一個頁,order2就是4個頁(16Kb)。
所以當獲得/proc/buddyinfo的時候,就得到如下信息:
Node 0, zone DMA32 7 20 2 4 6 4 3 4 6 5 369
以上的數據信息表示這臺機器上DMA32區域現在有7個4kb的內存塊(chunk,強調連續吧),20個8kb的chunk。以此類推,最後的369就是4kb*1024大小的頁了。因爲內核會按照需要把巨大的chunk變成小的chunk如果有需要的話。所以儘管看起來這個DMA32上order爲0的空間很少了,但是他的狀態還是不錯的。
(這也是爲什麼/proc/pagetypeinfo按照order進行排列的原因了)
事實上,有一個不成比例(很大比例的)的0-order的空間是一個可怕的信號,因爲它表示着碎片太多了,因爲內核已經甚至不能把他們組合成8-kb的頁了。
參考:proc文件系統說明書
到這裏這篇文章就結束了。
回到之前的那張表,看到這裏一切就清楚了。然後再看一下前面那個page block order和pages per block,這個我認爲大概就是給一個參考說明吧,也就說order爲9的時候,每一個block(應該就是前面文章中的chunk)有512個page,所以order爲0的時候就是1個page。