最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

說(shuō)出來(lái)你可能不信,內(nèi)核這家伙在內(nèi)存的使用上給自己開(kāi)了個(gè)小灶!

2022-07-07 14:46 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿




現(xiàn)在你可能還覺(jué)得node、zone、伙伴系統(tǒng)、slab這些東東還有那么一點(diǎn)點(diǎn)陌生。別怕,接下來(lái)我們結(jié)合動(dòng)手觀察,把它們逐個(gè)來(lái)展開(kāi)細(xì)說(shuō)。(下面的討論都基于Linux 3.10.0版本)


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ? ? ?

一、NODE 劃分

在現(xiàn)代的服務(wù)器上,內(nèi)存和CPU都是所謂的NUMA架構(gòu)


CPU往往不止是一顆。通過(guò)dmidecode命令看到你主板上插著的CPU的詳細(xì)信息

內(nèi)存也不只是一條。dmidecode同樣可以查看到服務(wù)器上插著的所有內(nèi)存條,也可以看到它是和哪個(gè)CPU直接連接的。

每一個(gè)CPU以及和他直連的內(nèi)存條組成了一個(gè) node(節(jié)點(diǎn))。



在你的機(jī)器上,你可以使用numactl你可以看到每個(gè)node的情況


二、ZONE 劃分

每個(gè) node 又會(huì)劃分成若干的 zone(區(qū)域) 。zone 表示內(nèi)存中的一塊范圍


  • ZONE_DMA:地址段最低的一塊內(nèi)存區(qū)域,ISA(Industry Standard Architecture)設(shè)備DMA訪問(wèn)

  • ZONE_DMA32:該Zone用于支持32-bits地址總線的DMA設(shè)備,只在64-bits系統(tǒng)里才有效

  • ZONE_NORMAL:在X86-64架構(gòu)下,DMA和DMA32之外的內(nèi)存全部在NORMAL的Zone里管理

為什么沒(méi)有提 ZONE_HIGHMEM 這個(gè)zone?因?yàn)檫@是 32 位機(jī)時(shí)代的產(chǎn)物?,F(xiàn)在應(yīng)該沒(méi)誰(shuí)在用這種古董了吧。

在每個(gè)zone下,都包含了許許多多個(gè) Page(頁(yè)面), 在linux下一個(gè)Page的大小一般是 4 KB。


在你的機(jī)器上,你可以使用通過(guò) zoneinfo 查看到你機(jī)器上 zone 的劃分,也可以看到每個(gè) zone 下所管理的頁(yè)面有多少個(gè)。

每個(gè)頁(yè)面大小是4K,很容易可以計(jì)算出每個(gè) zone 的大小。比如對(duì)于上面 Node1 的 Normal, 16514393 * 4K = 66 GB。

三、基于伙伴系統(tǒng)管理空閑頁(yè)面

每個(gè) zone 下面都有如此之多的頁(yè)面,Linux使用伙伴系統(tǒng)對(duì)這些頁(yè)面進(jìn)行高效的管理。在內(nèi)核中,表示 zone 的數(shù)據(jù)結(jié)構(gòu)是 struct zone。其下面的一個(gè)數(shù)組 free_area 管理了絕大部分可用的空閑頁(yè)面。這個(gè)數(shù)組就是伙伴系統(tǒng)實(shí)現(xiàn)的重要數(shù)據(jù)結(jié)構(gòu)。

free_area是一個(gè)11個(gè)元素的數(shù)組,在每一個(gè)數(shù)組分別代表的是空閑可分配連續(xù)4K、8K、16K、......、4M內(nèi)存鏈表。


通過(guò)cat /proc/pagetypeinfo, 你可以看到當(dāng)前系統(tǒng)里伙伴系統(tǒng)里各個(gè)尺寸的可用連續(xù)內(nèi)存塊數(shù)量。


內(nèi)核提供分配器函數(shù)alloc_pages到上面的多個(gè)鏈表中尋找可用連續(xù)頁(yè)面。

alloc_pages是怎么工作的呢?我們舉個(gè)簡(jiǎn)單的小例子。假如要申請(qǐng)8K-連續(xù)兩個(gè)頁(yè)框的內(nèi)存。為了描述方便,我們先暫時(shí)忽略UNMOVEABLE、RELCLAIMABLE等不同類型


伙伴系統(tǒng)中的伙伴指的是兩個(gè)內(nèi)存塊,大小相同,地址連續(xù),同屬于一個(gè)大塊區(qū)域。

基于伙伴系統(tǒng)的內(nèi)存分配中,有可能需要將大塊內(nèi)存拆分成兩個(gè)小伙伴。在釋放中,可能會(huì)將兩個(gè)小伙伴合并再次組成更大塊的連續(xù)內(nèi)存。

四、SLAB管理器

說(shuō)到現(xiàn)在,不知道你注意到?jīng)]有。目前我們介紹的內(nèi)存分配都是以頁(yè)面(4KB)為單位的。

對(duì)于各個(gè)內(nèi)核運(yùn)行中實(shí)際使用的對(duì)象來(lái)說(shuō),多大的對(duì)象都有。有的對(duì)象有1K多,但有的對(duì)象只有幾百、甚至幾十個(gè)字節(jié)。如果都直接分配一個(gè) 4K的頁(yè)面 來(lái)存儲(chǔ)的話也太敗家了,所以伙伴系統(tǒng)并不能直接使用。

在伙伴系統(tǒng)之上,內(nèi)核又給自己搞了一個(gè)專用的內(nèi)存分配器, 叫slab或slub。這兩個(gè)詞老混用,為了省事,接下來(lái)我們就統(tǒng)一叫 slab 吧。

這個(gè)分配器最大的特點(diǎn)就是,一個(gè)slab內(nèi)只分配特定大小、甚至是特定的對(duì)象。這樣當(dāng)一個(gè)對(duì)象釋放內(nèi)存后,另一個(gè)同類對(duì)象可以直接使用這塊內(nèi)存。通過(guò)這種辦法極大地降低了碎片發(fā)生的幾率。



slab相關(guān)的內(nèi)核對(duì)象定義如下:

每個(gè)cache都有滿、半滿、空三個(gè)鏈表。每個(gè)鏈表節(jié)點(diǎn)都對(duì)應(yīng)一個(gè) slab,一個(gè) slab 由 1 個(gè)或者多個(gè)內(nèi)存頁(yè)組成。

在每一個(gè) slab 內(nèi)都保存的是同等大小的對(duì)象。 一個(gè)cache的組成示意圖如下:


當(dāng) cache 中內(nèi)存不夠的時(shí)候,會(huì)調(diào)用基于伙伴系統(tǒng)的分配器(__alloc_pages函數(shù))請(qǐng)求整頁(yè)連續(xù)內(nèi)存的分配。

內(nèi)核中會(huì)有很多個(gè) kmem_cache 存在。它們是在linux初始化,或者是運(yùn)行的過(guò)程中分配出來(lái)的。它們有的是專用的,有的是通用的。



上圖中,我們看到 socket_alloc 內(nèi)核對(duì)象都存在 TCP的專用 kmem_cache 中。

通過(guò)查看 /proc/slabinfo 我們可以查看到所有的 kmem cache。



另外 linux 還提供了一個(gè)特別方便的命令 slabtop 來(lái)按照占用內(nèi)存從大往小進(jìn)行排列。這個(gè)命令用來(lái)分析 slab 內(nèi)存開(kāi)銷非常的方便。



無(wú)論是/proc/slabinfo,還是 slabtop 命令的輸出。里面都包含了每個(gè) cache 中 slab的如下兩個(gè)關(guān)鍵信息。

  • objsize:每個(gè)對(duì)象的大小

  • objperslab:一個(gè) slab 里存放的對(duì)象的數(shù)量

在 /proc/slabinfo 還多輸出了一個(gè)pagesperslab。展示了一個(gè)slab 占用的頁(yè)面的數(shù)量,每個(gè)頁(yè)面4K,這樣也就能算出每個(gè) slab 占用的內(nèi)存大小。

最后,slab 管理器組件提供了若干接口函數(shù),方便自己使用。舉三個(gè)例子:

  • kmem_cache_create: 方便地創(chuàng)建一個(gè)基于 slab 的內(nèi)核對(duì)象管理器。

  • kmem_cache_alloc: 快速為某個(gè)對(duì)象申請(qǐng)內(nèi)存

  • kmem_cache_free: 歸還對(duì)象占用的內(nèi)存給 slab 管理器

在內(nèi)核的源碼中,可以大量見(jiàn)到 kmem_cache 開(kāi)頭函數(shù)的使用。

總結(jié)

通過(guò)上面描述的幾個(gè)步驟,內(nèi)核高效地把內(nèi)存用了起來(lái)。



前三步是基礎(chǔ)模塊,為應(yīng)用程序分配內(nèi)存時(shí)的請(qǐng)求調(diào)頁(yè)組件也能夠用到。但第四步,就算是內(nèi)核的小灶了。內(nèi)核根據(jù)自己的使用場(chǎng)景,量身打造的一套自用的高效內(nèi)存分配管理機(jī)制。


“可以看到 TCP cache下每個(gè) slab 占用 8 個(gè) Page,也就是 8* 4096 = 32768KB。該對(duì)象的單個(gè)大小是 1984 字節(jié) 字節(jié),每個(gè)slab內(nèi)放了 16 個(gè)對(duì)象。1984*16=31744”

“這個(gè)時(shí)候再多放一個(gè) TCP 對(duì)象又放不下,剩下的 1K 內(nèi)存就只好“浪費(fèi)”掉了。但是鑒于 slab 機(jī)制整體提供的高性能、以及低碎片的效果,這一點(diǎn)點(diǎn)的額外開(kāi)銷還是很值得的?!?/p>



說(shuō)出來(lái)你可能不信,內(nèi)核這家伙在內(nèi)存的使用上給自己開(kāi)了個(gè)小灶!的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
吴桥县| 观塘区| 潞西市| 澎湖县| 温泉县| 应城市| 什邡市| 浙江省| 讷河市| 河东区| 莎车县| 交口县| 罗定市| 淳化县| 五原县| 九龙坡区| 巴林右旗| 皮山县| 五峰| 西丰县| 绥滨县| 无棣县| 吉安市| 临朐县| 泗水县| 仙居县| 巴彦县| 额尔古纳市| 紫金县| 闵行区| 莱西市| 鄂伦春自治旗| 古交市| 松溪县| 潮州市| 子长县| 揭阳市| 池州市| 莱州市| 大冶市| 桑植县|