精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

避開 Linux OOM:先懂動(dòng)態(tài)內(nèi)存管理

系統(tǒng) Linux
Linux 動(dòng)態(tài)內(nèi)存管理機(jī)制的靈活性和高效性體現(xiàn)在多個(gè)關(guān)鍵方面,為系統(tǒng)的穩(wěn)定運(yùn)行和高性能表現(xiàn)提供了有力支撐。

在 Linux 操作系統(tǒng)的龐大體系中,內(nèi)存管理堪稱核心樞紐,其重要性怎么強(qiáng)調(diào)都不為過。它就像是一位技藝精湛的大管家,有條不紊地掌控著系統(tǒng)內(nèi)存資源的分配與回收,確保整個(gè)系統(tǒng)穩(wěn)定、高效地運(yùn)行。從系統(tǒng)性能的角度來看,內(nèi)存管理直接影響著計(jì)算機(jī)的運(yùn)行速度和響應(yīng)能力。當(dāng)我們?cè)?Linux 系統(tǒng)中同時(shí)開啟多個(gè)應(yīng)用程序,或是運(yùn)行復(fù)雜的計(jì)算任務(wù)時(shí),高效的內(nèi)存管理機(jī)制能夠確保每個(gè)進(jìn)程都能及時(shí)獲得所需的內(nèi)存資源,避免因內(nèi)存不足而導(dǎo)致的程序卡頓甚至系統(tǒng)崩潰。這就好比在繁忙的交通樞紐,交通管理員合理地指揮車輛通行,使得道路保持暢通,車流暢行無阻。

在多任務(wù)處理環(huán)境下,內(nèi)存管理更是保障了各個(gè)進(jìn)程的獨(dú)立性和安全性。它為每個(gè)進(jìn)程分配獨(dú)立的內(nèi)存空間,使得不同進(jìn)程之間的內(nèi)存訪問相互隔離,避免了進(jìn)程間的內(nèi)存沖突和非法訪問,就如同為每個(gè)居民分配獨(dú)立的居住空間,保障了各自的隱私和安全。而動(dòng)態(tài)內(nèi)存管理機(jī)制,作為 Linux 內(nèi)存管理的關(guān)鍵組成部分,更是在運(yùn)行時(shí)根據(jù)程序的實(shí)際需求動(dòng)態(tài)地分配和釋放內(nèi)存,極大地提高了內(nèi)存的利用率和系統(tǒng)的靈活性,是我們深入理解 Linux 系統(tǒng)運(yùn)行機(jī)制的關(guān)鍵所在。接下來,就讓我們一同深入探索 Linux 動(dòng)態(tài)內(nèi)存管理機(jī)制的神秘世界吧。

一、Linux 內(nèi)存管理基礎(chǔ)概念

在深入探究 Linux 動(dòng)態(tài)內(nèi)存管理機(jī)制之前,我們先來夯實(shí)一下基礎(chǔ),了解幾個(gè)關(guān)鍵的內(nèi)存管理基礎(chǔ)概念,它們就像是搭建高樓大廈的基石,是我們后續(xù)深入學(xué)習(xí)的重要前提。

1.1 虛擬內(nèi)存與物理內(nèi)存

物理內(nèi)存,是計(jì)算機(jī)硬件層面實(shí)實(shí)在在存在的內(nèi)存條,通常也被稱為隨機(jī)存取存儲(chǔ)器(Random Access Memory,RAM) ,它就像是計(jì)算機(jī)的 “高速緩存區(qū)”,直接與 CPU 進(jìn)行數(shù)據(jù)交互,為正在運(yùn)行的程序提供即時(shí)的數(shù)據(jù)存儲(chǔ)和讀取服務(wù),其讀寫速度極快,能夠滿足 CPU 對(duì)數(shù)據(jù)的快速訪問需求,確保程序的高效運(yùn)行。例如,當(dāng)我們運(yùn)行一個(gè)辦公軟件時(shí),軟件的代碼和正在處理的數(shù)據(jù)就會(huì)被加載到物理內(nèi)存中,CPU 可以迅速從中讀取和寫入數(shù)據(jù),讓我們能夠流暢地進(jìn)行文字編輯、表格制作等操作。

而虛擬內(nèi)存則是 Linux 操作系統(tǒng)精心構(gòu)建的一種內(nèi)存管理機(jī)制,它為每個(gè)進(jìn)程營(yíng)造出一種擁有獨(dú)立且連續(xù)內(nèi)存空間的假象 ,讓進(jìn)程誤以為自己獨(dú)占了大量的內(nèi)存資源,而無需擔(dān)憂實(shí)際物理內(nèi)存的有限性和復(fù)雜布局。這就好比每個(gè)進(jìn)程都擁有一個(gè)專屬的 “虛擬大倉庫”,可以自由地規(guī)劃和使用內(nèi)存空間,而不必在意倉庫的實(shí)際大小和位置。虛擬內(nèi)存的實(shí)現(xiàn)依賴于硬盤空間,當(dāng)物理內(nèi)存不足時(shí),操作系統(tǒng)會(huì)將部分暫時(shí)不使用的內(nèi)存頁數(shù)據(jù)轉(zhuǎn)移到硬盤的交換空間(swap space)中保存起來 ,就像是把倉庫里暫時(shí)不用的貨物搬到了倉庫外的臨時(shí)存儲(chǔ)區(qū)。當(dāng)進(jìn)程再次需要這些數(shù)據(jù)時(shí),再將其從交換空間重新加載回物理內(nèi)存中,這個(gè)過程就如同從臨時(shí)存儲(chǔ)區(qū)取回貨物放回倉庫一樣。

虛擬內(nèi)存對(duì)于 Linux 系統(tǒng)而言,重要性不言而喻。它極大地拓展了系統(tǒng)的內(nèi)存使用范圍,使得系統(tǒng)能夠運(yùn)行那些內(nèi)存需求超過物理內(nèi)存容量的大型程序,為用戶提供了更為強(qiáng)大的計(jì)算能力和更豐富的應(yīng)用體驗(yàn)。同時(shí),虛擬內(nèi)存還在進(jìn)程隔離和內(nèi)存保護(hù)方面發(fā)揮著關(guān)鍵作用,它為每個(gè)進(jìn)程分配獨(dú)立的虛擬地址空間,使得進(jìn)程之間的內(nèi)存訪問相互隔離,避免了進(jìn)程間的內(nèi)存沖突和非法訪問,就像為每個(gè)倉庫都設(shè)置了獨(dú)立的門禁系統(tǒng),保障了各個(gè)倉庫的安全和隱私。

1.2 內(nèi)存空間劃分:用戶空間與內(nèi)核空間

在 Linux 系統(tǒng)中,虛擬內(nèi)存空間被細(xì)致地劃分為兩個(gè)重要部分:用戶空間和內(nèi)核空間 。對(duì)于 32 位操作系統(tǒng)來說,其尋址空間(虛擬地址空間)為 4GB,在這 4GB 的虛擬地址空間里,最高的 1GB 字節(jié)(從虛擬地址 0xC0000000 到 0xFFFFFFFF)被內(nèi)核所占用,這部分空間被稱為內(nèi)核空間 ;而較低的 3GB 字節(jié)(從虛擬地址 0x00000000 到 0xBFFFFFFF)則分配給各個(gè)進(jìn)程使用,這便是用戶空間 。可以這樣理解,每個(gè)進(jìn)程都擁有 4GB 的虛擬地址空間,其中最高的 1GB 是所有進(jìn)程共享的內(nèi)核空間,剩下的 3GB 才是進(jìn)程自己獨(dú)有的用戶空間。

用戶空間是應(yīng)用程序的 “專屬領(lǐng)地”,是用戶程序運(yùn)行的主場(chǎng)。在用戶空間中,進(jìn)程運(yùn)行在用戶地址空間內(nèi),被執(zhí)行的代碼要接受 CPU 的嚴(yán)格檢查,只能訪問映射其地址空間的頁表項(xiàng)中規(guī)定的在用戶態(tài)下可訪問頁面的虛擬地址 ,并且只能對(duì)任務(wù)狀態(tài)段(Task State Segment,TSS)中 I/O 許可位圖(I/O Permission Bitmap)里規(guī)定的可訪問端口進(jìn)行直接訪問 。簡(jiǎn)單來說,用戶空間的進(jìn)程就像是被 “戴上了枷鎖”,其操作權(quán)限受到了諸多限制,這樣的設(shè)計(jì)主要是為了保護(hù)系統(tǒng)的穩(wěn)定性和安全性,防止用戶程序的錯(cuò)誤操作或惡意行為對(duì)系統(tǒng)造成嚴(yán)重破壞。比如,當(dāng)我們運(yùn)行一個(gè)普通的游戲程序時(shí),這個(gè)游戲程序就在用戶空間中運(yùn)行,它只能訪問自己被分配的內(nèi)存區(qū)域和特定的端口,無法隨意篡改系統(tǒng)內(nèi)核數(shù)據(jù)或直接訪問硬件設(shè)備,從而確保了系統(tǒng)的穩(wěn)定運(yùn)行,不會(huì)因?yàn)橛螒虺绦虻谋罎⒍鴮?dǎo)致整個(gè)系統(tǒng)癱瘓。

內(nèi)核空間則是操作系統(tǒng)內(nèi)核的 “核心地帶”,是一個(gè)受到嚴(yán)格保護(hù)的區(qū)域,只有操作系統(tǒng)內(nèi)核以及與之緊密相關(guān)的程序才有資格訪問 。內(nèi)核空間擁有至高無上的權(quán)限,它可以直接訪問系統(tǒng)的硬件資源和內(nèi)核數(shù)據(jù)結(jié)構(gòu) ,能夠執(zhí)行特權(quán)指令,全面掌控操作系統(tǒng)內(nèi)核的所有功能 。內(nèi)核就像是系統(tǒng)的 “大管家”,負(fù)責(zé)系統(tǒng)的硬件管理、進(jìn)程調(diào)度、內(nèi)存管理、文件系統(tǒng)操作、網(wǎng)絡(luò)通信等一系列關(guān)鍵任務(wù) ,為上層應(yīng)用程序提供穩(wěn)定、高效的運(yùn)行環(huán)境和豐富的服務(wù)接口。

例如,當(dāng)我們?cè)?Linux 系統(tǒng)中進(jìn)行文件讀寫操作時(shí),應(yīng)用程序會(huì)通過系統(tǒng)調(diào)用向內(nèi)核發(fā)起請(qǐng)求,內(nèi)核在接收到請(qǐng)求后,會(huì)在內(nèi)核空間中完成對(duì)磁盤的實(shí)際讀寫操作,然后將數(shù)據(jù)返回給用戶空間的應(yīng)用程序,整個(gè)過程就像是用戶向管家提出需求,管家負(fù)責(zé)具體執(zhí)行并將結(jié)果反饋給用戶。

二、動(dòng)態(tài)內(nèi)存管理機(jī)制原理

2.1 分頁機(jī)制

分頁機(jī)制是 Linux 動(dòng)態(tài)內(nèi)存管理的重要基石,它巧妙地將程序的邏輯地址空間和物理內(nèi)存劃分為固定大小的頁(page)和頁框(page frame) ,就像是把一本厚厚的書籍按照固定的章節(jié)(頁)進(jìn)行劃分,每個(gè)章節(jié)都有對(duì)應(yīng)的書架位置(頁框)。在 Linux 系統(tǒng)中,頁的大小通常為 4KB ,當(dāng)然,根據(jù)不同的系統(tǒng)配置和硬件平臺(tái),頁的大小也可能會(huì)有所調(diào)整,比如在一些高性能計(jì)算場(chǎng)景中,可能會(huì)采用更大的頁大小來提高內(nèi)存訪問效率。

在分頁機(jī)制下,程序加載時(shí),系統(tǒng)可以將任意一頁放入內(nèi)存中的任意一個(gè)頁框,這些頁框不必連續(xù) ,這就如同書籍的章節(jié)可以分散放置在書架的不同位置,只要有對(duì)應(yīng)的索引(頁表)能夠找到它們即可。這種離散分配方式極大地提高了內(nèi)存的利用率,有效避免了連續(xù)分配內(nèi)存時(shí)可能出現(xiàn)的內(nèi)存碎片問題 ,就像把書籍隨意擺放,只要有索引就能找到想要的章節(jié),而不會(huì)因?yàn)闀芸臻g不連續(xù)而無法放置書籍。

分頁機(jī)制如何啟用:

在我們進(jìn)行程序開發(fā)的時(shí)候,一般情況下,是不需要管理內(nèi)存的,也不需要操心內(nèi)存夠不夠用,其實(shí),這就是分頁機(jī)制給我們帶來的好處。它是實(shí)現(xiàn)虛擬存儲(chǔ)的關(guān)鍵,位于線性地址與物理地址之間,在使用這種內(nèi)存分頁管理方法時(shí),每個(gè)執(zhí)行中的進(jìn)程(任務(wù))可以使用比實(shí)際內(nèi)存容量大得多的連續(xù)地址空間。而且當(dāng)系統(tǒng)內(nèi)存實(shí)際上被分成很多凌亂的塊時(shí),它可以建立一個(gè)大而連續(xù)的內(nèi)存空間的映象,好讓程序不用操心和管理這些分散的內(nèi)存塊。分頁機(jī)制增強(qiáng)了分段機(jī)制的性能。頁地址變換是建立在段變換基礎(chǔ)之上的。因?yàn)椋喂芾頇C(jī)制對(duì)于Intel處理器來說是最基本的,任何時(shí)候都無法關(guān)閉。所以即使啟用了頁管理功能,分段機(jī)制依然是起作用的,段部件也依然工作。

分頁只能在保護(hù)模式(CR0.PE = 1)下使用。在保護(hù)模式下,是否開啟分頁,由 CR0. PG 位(位 31)決定:

  • 當(dāng) CR0.PG = 0 時(shí),未開啟分頁,線性地址等同于物理地址;
  • 當(dāng) CR0.PG = 1 時(shí),開啟分頁。

為了實(shí)現(xiàn)虛擬頁到物理頁框的映射,Linux 使用了多級(jí)頁表 ,這就像是一個(gè)復(fù)雜的目錄系統(tǒng),通過層層索引,能夠快速準(zhǔn)確地找到所需的頁面。以常見的四級(jí)頁表為例,當(dāng) CPU 訪問一個(gè)虛擬地址時(shí),它會(huì)首先根據(jù)虛擬地址的高位部分索引頁全局目錄(Page Global Directory,PGD) ,就像在一個(gè)大型圖書館中,首先通過總目錄找到對(duì)應(yīng)的書架區(qū)域;然后使用頁全局目錄項(xiàng)的高位部分索引頁上級(jí)目錄(Page Upper Directory,PUD) ,接著再通過頁上級(jí)目錄項(xiàng)的高位部分索引頁中間目錄(Page Middle Directory,PMD) ,最后使用頁中間目錄項(xiàng)的高位部分索引頁表(Page Table Entry,PTE) ,從而得到物理頁框號(hào),再結(jié)合虛擬地址的低位部分(頁內(nèi)偏移),就可以計(jì)算出最終的物理地址 。整個(gè)過程就像是在圖書館中,通過層層目錄找到具體的書籍位置。

在這個(gè)過程中,為了加速地址轉(zhuǎn)換,CPU 還引入了快表(Translation Lookaside Buffer,TLB) ,它就像是一個(gè)常用書籍的快速索引,緩存了最近訪問的頁表項(xiàng) 。當(dāng) CPU 進(jìn)行地址轉(zhuǎn)換時(shí),會(huì)首先在 TLB 中查找,如果能夠找到對(duì)應(yīng)的頁表項(xiàng),就可以直接得到物理地址,而無需再去訪問內(nèi)存中的頁表,大大提高了地址轉(zhuǎn)換的速度 ,就像我們?cè)诓檎页S脮畷r(shí),可以直接通過快速索引找到,而不必再去翻閱整個(gè)目錄。只有當(dāng) TLB 中沒有命中時(shí),才會(huì)去內(nèi)存中查詢頁表,這就好比快速索引中沒有找到書籍,才需要去翻閱總目錄。

2.2 分段機(jī)制(簡(jiǎn)單提及與分頁的配合)

Linux 的分段機(jī)制將程序的地址空間劃分為多個(gè)邏輯段,如代碼段、數(shù)據(jù)段、堆棧段等 ,每個(gè)段都有自己的基地址、限長(zhǎng)和訪問權(quán)限等屬性 ,就像是將一個(gè)大型工廠劃分為不同的車間,每個(gè)車間都有自己的工作區(qū)域、工作范圍和進(jìn)入權(quán)限。分段機(jī)制最初是為了滿足程序模塊化設(shè)計(jì)和內(nèi)存保護(hù)的需求而誕生的,它在早期的操作系統(tǒng)內(nèi)存管理中發(fā)揮了重要作用 ,就像工廠的車間劃分,有利于不同工作的開展和管理。

在現(xiàn)代 Linux 系統(tǒng)中,雖然分頁機(jī)制在內(nèi)存管理中占據(jù)主導(dǎo)地位,但分段機(jī)制仍然存在,并與分頁機(jī)制協(xié)同工作 ,共同保障系統(tǒng)的穩(wěn)定運(yùn)行。分段機(jī)制主要用于權(quán)限審核 ,它通過段描述符中的權(quán)限字段來判斷當(dāng)前程序是否有權(quán)限訪問特定的內(nèi)存段 ,就像車間的門禁系統(tǒng),根據(jù)權(quán)限來控制人員的進(jìn)出。例如,用戶態(tài)程序只能訪問用戶空間的內(nèi)存段,而內(nèi)核態(tài)程序則可以訪問內(nèi)核空間的內(nèi)存段,當(dāng)用戶態(tài)程序試圖訪問內(nèi)核空間的內(nèi)存時(shí),分段機(jī)制會(huì)進(jìn)行權(quán)限檢查,并阻止這種非法訪問 ,從而保護(hù)了系統(tǒng)內(nèi)核的安全,避免了用戶程序的錯(cuò)誤操作或惡意行為對(duì)內(nèi)核造成破壞,就像沒有權(quán)限的人員試圖進(jìn)入限制區(qū)域,會(huì)被門禁系統(tǒng)阻攔。

在實(shí)際的內(nèi)存訪問過程中,邏輯地址首先會(huì)經(jīng)過分段機(jī)制的轉(zhuǎn)換,生成線性地址 ,然后線性地址再經(jīng)過分頁機(jī)制的轉(zhuǎn)換,最終得到物理地址 ,這就好比貨物在運(yùn)輸過程中,首先要經(jīng)過區(qū)域劃分的檢查,然后再根據(jù)具體的位置信息找到存放的倉庫。不過,在 Linux 系統(tǒng)中,為了簡(jiǎn)化內(nèi)存管理和提高性能,大部分情況下,分段機(jī)制的作用被弱化,所有段的基地址都被設(shè)置為 0 ,使得線性地址和邏輯地址在數(shù)值上相等 ,就像是區(qū)域劃分的范圍變得非常簡(jiǎn)單,幾乎可以忽略不計(jì),這樣就可以讓分頁機(jī)制更加高效地發(fā)揮作用,就像簡(jiǎn)化了運(yùn)輸過程中的一個(gè)環(huán)節(jié),提高了運(yùn)輸效率。

2.3 內(nèi)存映射(mmap)與 brk

在 Linux 系統(tǒng)中,內(nèi)存映射(mmap)和 brk 是兩種重要的內(nèi)存分配方式,它們各自有著獨(dú)特的原理、特點(diǎn)和適用場(chǎng)景。全面解析請(qǐng)考這篇文章《解鎖Linux內(nèi)存映射:讓你的程序飛起來》。

mmap 是一種強(qiáng)大的內(nèi)存分配機(jī)制,它通過系統(tǒng)調(diào)用在進(jìn)程的虛擬地址空間中創(chuàng)建一個(gè)新的映射區(qū)域 ,可以將文件、設(shè)備或者匿名內(nèi)存映射到該區(qū)域 ,使得進(jìn)程可以像訪問普通內(nèi)存一樣對(duì)映射的內(nèi)容進(jìn)行讀寫操作 ,就像是在自己的倉庫中開辟了一個(gè)特殊區(qū)域,這個(gè)區(qū)域與外部的文件倉庫或者其他存儲(chǔ)設(shè)備建立了直接的聯(lián)系,我們可以直接在自己的倉庫中對(duì)外部倉庫的貨物進(jìn)行操作。當(dāng)我們使用 mmap 將一個(gè)文件映射到內(nèi)存中時(shí),對(duì)該文件的讀寫操作就可以通過普通的內(nèi)存訪問指令來完成,而無需進(jìn)行傳統(tǒng)的文件 I/O 操作,大大提高了數(shù)據(jù)訪問的效率 ,就像我們不需要再通過繁瑣的手續(xù)去外部倉庫取貨,而是直接在自己倉庫的特殊區(qū)域就能拿到貨物并進(jìn)行處理。

mmap 支持多種映射模式,如共享映射(MAP_SHARED)和私有映射(MAP_PRIVATE) 。在共享映射模式下,多個(gè)進(jìn)程可以共享同一個(gè)映射區(qū)域,對(duì)映射區(qū)域的修改會(huì)直接反映到被映射的文件或其他進(jìn)程中 ,就像多個(gè)用戶共同使用一個(gè)公共倉庫,任何一個(gè)用戶對(duì)倉庫貨物的修改,其他用戶都能看到;而在私有映射模式下,每個(gè)進(jìn)程對(duì)映射區(qū)域的修改都是私有的,不會(huì)影響到其他進(jìn)程和被映射的文件 ,就像每個(gè)用戶都有自己獨(dú)立的小倉庫,雖然倉庫與公共倉庫有聯(lián)系,但自己對(duì)小倉庫的修改不會(huì)影響到公共倉庫和其他用戶的小倉庫。這種靈活性使得 mmap 在實(shí)現(xiàn)文件映射、共享內(nèi)存、進(jìn)程間通信等場(chǎng)景中得到了廣泛的應(yīng)用 ,比如在多個(gè)進(jìn)程需要共享數(shù)據(jù)的場(chǎng)景下,就可以使用共享映射模式來實(shí)現(xiàn)高效的數(shù)據(jù)共享和通信。

brk 則是一種更為傳統(tǒng)的內(nèi)存分配方式,它通過調(diào)整進(jìn)程數(shù)據(jù)段(data segment)的結(jié)束地址(_edata)來擴(kuò)展或收縮堆(heap)空間 ,就像是在自己的倉庫中,通過移動(dòng)倉庫的邊界來擴(kuò)大或縮小存儲(chǔ)貨物的空間。當(dāng)進(jìn)程需要更多的堆內(nèi)存時(shí),調(diào)用 brk 函數(shù)將_edata 指針向上移動(dòng),從而擴(kuò)大堆區(qū)的大小 ;當(dāng)不再需要這些內(nèi)存時(shí),將_edata 指針向下移動(dòng),縮小堆區(qū)大小,釋放內(nèi)存 ,這個(gè)過程就像我們根據(jù)貨物的多少,調(diào)整倉庫的大小。brk 分配的內(nèi)存是連續(xù)的 ,這在某些對(duì)內(nèi)存連續(xù)性要求較高的應(yīng)用場(chǎng)景中非常重要,因?yàn)檫B續(xù)內(nèi)存有利于提高緩存命中率 ,就像把相似的貨物放在相鄰的位置,方便快速取用。

不過,brk 也存在一些局限性 。由于它只能分配連續(xù)的內(nèi)存塊,隨著頻繁的內(nèi)存分配和釋放,容易導(dǎo)致內(nèi)存碎片化問題 ,即大量的小塊內(nèi)存碎片散布在內(nèi)存空間中,使得后續(xù)無法滿足大塊內(nèi)存的需求 ,就像倉庫中貨物擺放雜亂,出現(xiàn)了很多小的空閑區(qū)域,無法存放大型貨物。而且 brk 是 Linux 特有的系統(tǒng)調(diào)用,并不保證在所有操作系統(tǒng)上都有相同的接口和行為 ,因此在跨平臺(tái)應(yīng)用開發(fā)時(shí)需要謹(jǐn)慎使用 ,就像不同的倉庫管理規(guī)則不同,在多個(gè)倉庫之間搬運(yùn)貨物時(shí)需要注意規(guī)則的差異。

mmap 和 brk 在內(nèi)存分配和管理方面各有優(yōu)劣 。mmap 靈活性高,適用于大文件 I/O、共享內(nèi)存、進(jìn)程間通信等場(chǎng)景 ,能夠充分利用現(xiàn)代操作系統(tǒng)的特性來優(yōu)化性能 ;而 brk 則簡(jiǎn)單高效,適合頻繁分配和釋放小內(nèi)存的場(chǎng)景 ,如字符串、結(jié)構(gòu)體等小型數(shù)據(jù)結(jié)構(gòu)的內(nèi)存管理 ,在追求極致效率的簡(jiǎn)單內(nèi)部對(duì)象存儲(chǔ)場(chǎng)景中具有一定的優(yōu)勢(shì) 。在實(shí)際的編程實(shí)踐中,開發(fā)者需要根據(jù)具體的應(yīng)用需求和場(chǎng)景來選擇合適的內(nèi)存分配方式 ,以實(shí)現(xiàn)最佳的性能和資源利用效率 ,就像在不同的工作場(chǎng)景中,選擇合適的工具才能更好地完成任務(wù)。

2.4 slab 分配器

在 Linux 內(nèi)核的內(nèi)存管理體系中,slab 分配器就像是一位專門負(fù)責(zé)小內(nèi)存管理的 “專家”,它主要用于高效管理小塊內(nèi)存的分配,在頻繁分配和釋放小對(duì)象的場(chǎng)景中發(fā)揮著至關(guān)重要的作用 。全面解析請(qǐng)參考這篇文章《解密Slab分配器:內(nèi)存管理的高效武器》。

slab 分配器的工作原理基于對(duì)象復(fù)用和緩存機(jī)制 。它會(huì)為每種類型的對(duì)象創(chuàng)建一個(gè)緩存(Cache) ,每個(gè)緩存存儲(chǔ)相同大小的對(duì)象集合 ,就像是為不同類型的小零件分別準(zhǔn)備了專門的收納盒,每個(gè)收納盒里只存放相同規(guī)格的小零件。當(dāng)有內(nèi)存分配請(qǐng)求時(shí),slab 分配器會(huì)首先從對(duì)應(yīng)的緩存中查找空閑對(duì)象 ,如果找到,就直接將其返回給請(qǐng)求者 ,這就好比在收納盒中尋找空閑的小零件,找到了就直接拿出來使用,避免了頻繁地向系統(tǒng)申請(qǐng)新的內(nèi)存 ,大大提高了內(nèi)存分配的效率 。只有當(dāng)緩存中沒有空閑對(duì)象時(shí),slab 分配器才會(huì)向底層的伙伴系統(tǒng)(Buddy System)申請(qǐng)新的內(nèi)存塊 ,并將其劃分為多個(gè)小對(duì)象放入緩存中 ,就像收納盒空了,再去大倉庫領(lǐng)取一批小零件,放入收納盒中備用。

當(dāng)對(duì)象不再使用時(shí),它并不會(huì)被立即釋放回系統(tǒng) ,而是被標(biāo)記為空閑,放回對(duì)應(yīng)的緩存中 ,等待下一次分配 ,這就像小零件用完后,不扔掉,而是放回收納盒中,下次還能繼續(xù)使用 ,這種對(duì)象復(fù)用的方式有效地減少了內(nèi)存碎片的產(chǎn)生 ,提高了內(nèi)存的利用率 。slab 分配器還支持緩存著色(cache coloring)等優(yōu)化技術(shù) ,通過將對(duì)象分布在不同的緩存行中 ,避免緩存行沖突 ,從而提高 CPU 緩存的命中率 ,進(jìn)一步提升了系統(tǒng)性能 ,就像合理地?cái)[放小零件,讓它們更容易被快速找到和使用。

slab 分配器在 Linux 內(nèi)核的眾多子系統(tǒng)中得到了廣泛應(yīng)用 。在網(wǎng)絡(luò)緩沖區(qū)管理中,網(wǎng)絡(luò)數(shù)據(jù)包的收發(fā)需要頻繁地分配和釋放小內(nèi)存塊來存儲(chǔ)數(shù)據(jù)包 ,slab 分配器能夠快速響應(yīng)這些請(qǐng)求 ,確保網(wǎng)絡(luò)通信的高效進(jìn)行 ;在文件系統(tǒng)緩存中,文件的讀寫操作也涉及到大量小內(nèi)存對(duì)象的管理 ,slab 分配器可以有效地管理這些緩存對(duì)象 ,提高文件系統(tǒng)的性能 ;在進(jìn)程控制塊(PCB)的管理中,每個(gè)進(jìn)程都有一個(gè)對(duì)應(yīng)的 PCB ,用于存儲(chǔ)進(jìn)程的相關(guān)信息 ,slab 分配器可以為 PCB 的分配和釋放提供高效的支持 ,保障進(jìn)程的正常運(yùn)行 。可以說,slab 分配器是 Linux 內(nèi)核實(shí)現(xiàn)高效內(nèi)存管理的關(guān)鍵組件之一 ,為整個(gè)系統(tǒng)的穩(wěn)定運(yùn)行和高性能表現(xiàn)提供了有力的支持。

三、動(dòng)態(tài)內(nèi)存分配與釋放過程

3.1 malloc 函數(shù)剖析

在 C 語言的標(biāo)準(zhǔn)庫中,malloc函數(shù)是實(shí)現(xiàn)動(dòng)態(tài)內(nèi)存分配的關(guān)鍵工具,它的定義為void *malloc(size_t size);,接受一個(gè)參數(shù)size,用于指定需要分配的內(nèi)存字節(jié)數(shù),返回值是一個(gè)指向所分配內(nèi)存起始地址的指針,類型為void*,這意味著它可以被轉(zhuǎn)換為任何類型的指針,以適應(yīng)不同的數(shù)據(jù)存儲(chǔ)需求。

在 Linux 系統(tǒng)中,malloc函數(shù)并非直接與操作系統(tǒng)的底層內(nèi)存管理機(jī)制打交道,而是通過glibc(GNU C Library)來實(shí)現(xiàn)的 。當(dāng)程序調(diào)用malloc函數(shù)時(shí),它首先會(huì)在glibc維護(hù)的內(nèi)存池中查找是否有足夠的空閑內(nèi)存來滿足請(qǐng)求 。如果內(nèi)存池中有足夠的空閑內(nèi)存,malloc函數(shù)會(huì)直接從內(nèi)存池中分配內(nèi)存,并返回相應(yīng)的指針 。這樣做可以減少系統(tǒng)調(diào)用的開銷,提高內(nèi)存分配的效率,因?yàn)橄到y(tǒng)調(diào)用涉及到用戶態(tài)和內(nèi)核態(tài)的切換,這種切換會(huì)帶來一定的性能損耗。

若內(nèi)存池中的空閑內(nèi)存不足以滿足請(qǐng)求,malloc函數(shù)就需要借助系統(tǒng)調(diào)用與操作系統(tǒng)進(jìn)行交互 。在 Linux 系統(tǒng)中,主要涉及到兩個(gè)系統(tǒng)調(diào)用:brk和mmap 。brk系統(tǒng)調(diào)用通過移動(dòng)程序數(shù)據(jù)段的結(jié)束地址(即 “堆頂” 指針)來增加堆的大小,從而分配新的內(nèi)存 ;而mmap系統(tǒng)調(diào)用則是通過在文件映射區(qū)域分配一塊內(nèi)存來滿足請(qǐng)求 。通常情況下,當(dāng)請(qǐng)求的內(nèi)存大小小于一定閾值(在大多數(shù)系統(tǒng)中,這個(gè)閾值通常為 128KB )時(shí),malloc函數(shù)會(huì)優(yōu)先使用brk系統(tǒng)調(diào)用來分配內(nèi)存;當(dāng)請(qǐng)求的內(nèi)存大小大于這個(gè)閾值時(shí),則會(huì)使用mmap系統(tǒng)調(diào)用。

malloc函數(shù)背后還依靠空閑鏈表來管理內(nèi)存 。當(dāng)調(diào)用malloc函數(shù)時(shí),它會(huì)沿著空閑鏈表查找滿足用戶請(qǐng)求大小的內(nèi)存塊 。若鏈表上存在多個(gè)不同大小的空閑內(nèi)存塊,它會(huì)依次遍歷這些塊來找到合適的那一個(gè) 。找到合適的內(nèi)存塊后,如果這個(gè)內(nèi)存塊比用戶請(qǐng)求的大小要大,就會(huì)按需將其分割成兩部分,一部分的大小剛好與用戶請(qǐng)求的大小相等,這部分分配給用戶使用,而剩下的那部分則放回空閑鏈表中,等待后續(xù)其他的內(nèi)存分配請(qǐng)求再進(jìn)行分配 。例如,空閑鏈表中有一個(gè) 50 字節(jié)的空閑塊,而用戶請(qǐng)求分配 20 字節(jié)的內(nèi)存,這時(shí)malloc就會(huì)把這個(gè) 50 字節(jié)的塊分成 20 字節(jié)(分配給用戶)和 30 字節(jié)(放回空閑鏈表)兩塊。

隨著程序不斷地分配和釋放內(nèi)存,空閑鏈表有可能會(huì)被切成很多的小內(nèi)存片段 。要是后續(xù)用戶申請(qǐng)一個(gè)較大的內(nèi)存片段時(shí),空閑鏈表上可能暫時(shí)沒有可以滿足要求的片段了,這時(shí)malloc函數(shù)可能就需要進(jìn)行一些整理操作,比如對(duì)這些小的空閑塊嘗試合并等,以便能滿足較大內(nèi)存請(qǐng)求的情況。

3.2 free 函數(shù)解析

free函數(shù)是 C 語言標(biāo)準(zhǔn)庫中用于釋放動(dòng)態(tài)分配內(nèi)存的重要函數(shù),其原型定義在<stdlib.h>頭文件中:void free(void *ptr); ,參數(shù)ptr指向已經(jīng)動(dòng)態(tài)分配內(nèi)存塊的指針,這個(gè)內(nèi)存塊應(yīng)該由malloc、calloc或realloc等函數(shù)返回 ,free函數(shù)沒有返回值,它的作用是將ptr指向的內(nèi)存塊歸還給系統(tǒng)進(jìn)行管理。

當(dāng)調(diào)用free函數(shù)釋放內(nèi)存時(shí),相應(yīng)被釋放的內(nèi)存塊并不會(huì)立即返還給操作系統(tǒng) ,而是返還給 C/C++ 的運(yùn)行時(shí)庫 。運(yùn)行時(shí)庫會(huì)將其標(biāo)記為空閑,并重新連接到空閑鏈表上 ,等待下一次內(nèi)存分配請(qǐng)求時(shí)再次被使用 。這就好比在一個(gè)圖書館借書系統(tǒng)中,讀者歸還的書籍并不會(huì)立即被送回總倉庫,而是先放在圖書館的歸還書架上,等待其他讀者借閱 。只有當(dāng)運(yùn)行時(shí)庫認(rèn)為有必要時(shí),比如一大塊位于堆頂部的連續(xù)內(nèi)存被釋放,且空閑內(nèi)存達(dá)到一定的閾值,運(yùn)行時(shí)庫才會(huì)考慮將其真正地歸還給操作系統(tǒng) ,以釋放物理內(nèi)存資源,供其他進(jìn)程使用。

在實(shí)際使用free函數(shù)時(shí),需要特別注意避免一些常見的錯(cuò)誤 。比如雙重釋放(Double Free),即對(duì)同一塊內(nèi)存進(jìn)行兩次free調(diào)用,這會(huì)導(dǎo)致程序崩潰或內(nèi)存破壞 。為了防止雙重釋放,應(yīng)在釋放內(nèi)存后將指針設(shè)為NULL,這樣可以避免第二次調(diào)用free時(shí)出錯(cuò) 。釋放空指針是安全的,free函數(shù)會(huì)忽略NULL指針,因此無需擔(dān)心釋放空指針帶來的問題 。釋放內(nèi)存后,原指針指向的內(nèi)存不再有效,繼續(xù)訪問該內(nèi)存區(qū)域會(huì)導(dǎo)致未定義行為,即訪問已釋放的內(nèi)存(懸空指針),為避免懸空指針,應(yīng)該在free后立即將指針設(shè)為NULL。

四、內(nèi)存回收機(jī)制

4.1 內(nèi)存回收的觸發(fā)條件

在 Linux 系統(tǒng)運(yùn)行過程中,內(nèi)存回收機(jī)制是保障系統(tǒng)穩(wěn)定運(yùn)行的重要防線,它會(huì)在多種情況下被觸發(fā),以應(yīng)對(duì)內(nèi)存資源緊張的局面。

當(dāng)系統(tǒng)內(nèi)存使用率持續(xù)攀升,達(dá)到一定閾值,可用內(nèi)存量急劇減少,接近或低于系統(tǒng)設(shè)定的警戒水位時(shí),內(nèi)存回收機(jī)制就會(huì)被緊急啟動(dòng) 。這就好比一個(gè)水庫,當(dāng)水位持續(xù)下降,接近警戒線時(shí),就需要采取措施來補(bǔ)充水量,以確保水庫的正常運(yùn)行。例如,當(dāng)系統(tǒng)中同時(shí)運(yùn)行多個(gè)大型程序,如大型數(shù)據(jù)庫管理系統(tǒng)、圖形渲染軟件等,它們對(duì)內(nèi)存的需求量巨大,會(huì)迅速消耗系統(tǒng)的內(nèi)存資源,導(dǎo)致可用內(nèi)存不足,此時(shí)內(nèi)存回收機(jī)制就會(huì)介入,回收一些暫時(shí)不用的內(nèi)存,以滿足這些程序的運(yùn)行需求。

當(dāng)有新的內(nèi)存分配請(qǐng)求出現(xiàn),而當(dāng)前系統(tǒng)的剩余內(nèi)存無法滿足這一請(qǐng)求時(shí),為了滿足新的內(nèi)存需求,系統(tǒng)會(huì)立即觸發(fā)內(nèi)存回收操作 。這就像是在一個(gè)資源有限的倉庫中,當(dāng)有新的貨物需要存放,而倉庫空間不足時(shí),就需要清理出一些空間來存放新貨物。比如,在運(yùn)行一個(gè)需要大量?jī)?nèi)存的機(jī)器學(xué)習(xí)訓(xùn)練任務(wù)時(shí),程序在運(yùn)行過程中可能會(huì)動(dòng)態(tài)申請(qǐng)更多的內(nèi)存來存儲(chǔ)中間數(shù)據(jù),如果此時(shí)系統(tǒng)內(nèi)存不足,就會(huì)觸發(fā)內(nèi)存回收,從其他進(jìn)程或緩存中回收內(nèi)存,以保證機(jī)器學(xué)習(xí)任務(wù)的順利進(jìn)行。

除了內(nèi)存緊張的情況外,當(dāng)進(jìn)程結(jié)束運(yùn)行時(shí),其占用的內(nèi)存資源也會(huì)被回收 。這就好比一個(gè)租客退租后,其所占用的房屋空間會(huì)被房東收回,以便重新分配給其他租客。進(jìn)程結(jié)束時(shí),操作系統(tǒng)會(huì)自動(dòng)回收該進(jìn)程所占用的用戶空間內(nèi)存,包括堆內(nèi)存、棧內(nèi)存等 ,同時(shí)也會(huì)清理該進(jìn)程在內(nèi)核空間中占用的相關(guān)資源,如文件描述符、進(jìn)程控制塊等 ,將這些內(nèi)存和資源重新歸還給系統(tǒng)內(nèi)存池,供其他進(jìn)程使用。

4.2 匿名頁與文件頁的回收策略

在 Linux 系統(tǒng)的內(nèi)存回收體系中,匿名頁和文件頁由于其特性的差異,采用了不同的回收策略。

匿名頁,是指那些沒有與任何文件建立映射關(guān)系的內(nèi)存頁,通常用于進(jìn)程的堆內(nèi)存和棧內(nèi)存等動(dòng)態(tài)分配的內(nèi)存區(qū)域 。當(dāng)內(nèi)存緊張需要回收匿名頁時(shí),如果系統(tǒng)配置了交換空間(swap space),那么系統(tǒng)會(huì)優(yōu)先將那些近期最少使用(Least Recently Used,LRU)的匿名頁換出到交換空間中存儲(chǔ) 。這就好比在一個(gè)倉庫中,將那些長(zhǎng)時(shí)間沒有被使用的貨物暫時(shí)搬到倉庫外的臨時(shí)存儲(chǔ)區(qū)存放。

當(dāng)進(jìn)程再次訪問這些被換出的匿名頁時(shí),系統(tǒng)會(huì)將其從交換空間重新?lián)Q入到物理內(nèi)存中 ,就像從臨時(shí)存儲(chǔ)區(qū)把貨物重新搬回倉庫。這個(gè)過程雖然解決了內(nèi)存緊張的問題,但由于磁盤的讀寫速度遠(yuǎn)遠(yuǎn)低于物理內(nèi)存,頻繁的換入換出操作會(huì)導(dǎo)致系統(tǒng)性能大幅下降,就像頻繁地在倉庫和臨時(shí)存儲(chǔ)區(qū)之間搬運(yùn)貨物,會(huì)耗費(fèi)大量的時(shí)間和精力。

文件頁,是指那些與文件系統(tǒng)中的文件建立了映射關(guān)系的內(nèi)存頁 。對(duì)于文件頁的回收,系統(tǒng)會(huì)首先判斷其是否為臟頁(dirty page) 。臟頁是指內(nèi)存中的數(shù)據(jù)與磁盤上的文件數(shù)據(jù)不一致的頁面,即內(nèi)存中的數(shù)據(jù)被修改后還沒有同步到磁盤上 。如果文件頁是干凈頁(clean page),即內(nèi)存中的數(shù)據(jù)與磁盤上的文件數(shù)據(jù)一致,那么系統(tǒng)可以直接將其釋放,因?yàn)楫?dāng)需要再次訪問這些數(shù)據(jù)時(shí),可以直接從磁盤中讀取 ,這就好比在一個(gè)圖書館中,如果一本書的內(nèi)容在書架上和圖書館的數(shù)據(jù)庫中是一致的,那么當(dāng)書架空間緊張時(shí),可以直接把這本書從書架上拿走,需要時(shí)再從數(shù)據(jù)庫中調(diào)取。

而對(duì)于臟頁,系統(tǒng)需要先將其數(shù)據(jù)寫回到磁盤上,使內(nèi)存中的數(shù)據(jù)與磁盤上的數(shù)據(jù)保持一致,然后才能將其釋放 ,就像在圖書館中,如果一本書的內(nèi)容被修改了,需要先把修改后的內(nèi)容保存到數(shù)據(jù)庫中,然后才能把這本書從書架上拿走 。這個(gè)過程涉及到磁盤 I/O 操作,雖然也會(huì)對(duì)系統(tǒng)性能產(chǎn)生一定影響,但相較于匿名頁的換入換出,其影響相對(duì)較小。

4.3 swap 空間的作用與原理

swap 空間,也被稱為交換空間,在 Linux 系統(tǒng)的內(nèi)存管理中扮演著至關(guān)重要的角色,它就像是系統(tǒng)內(nèi)存的 “后備倉庫” ,主要用于在物理內(nèi)存不足時(shí),暫時(shí)存儲(chǔ)那些被換出的內(nèi)存頁數(shù)據(jù),以緩解內(nèi)存緊張的局面 ,保障系統(tǒng)的穩(wěn)定運(yùn)行。

swap 空間的工作原理基于數(shù)據(jù)交換機(jī)制 。當(dāng)系統(tǒng)的物理內(nèi)存資源緊張,無法滿足所有進(jìn)程的內(nèi)存需求時(shí),操作系統(tǒng)會(huì)將一些暫時(shí)不使用或近期最少使用的內(nèi)存頁數(shù)據(jù)從物理內(nèi)存中換出(swap out) ,寫入到 swap 空間中存儲(chǔ) ,就像把倉庫中暫時(shí)不用的貨物搬到臨時(shí)存儲(chǔ)區(qū)存放。這樣,物理內(nèi)存中就騰出了空間,可以用于滿足其他更急需內(nèi)存的進(jìn)程的需求 。當(dāng)被換出的內(nèi)存頁數(shù)據(jù)再次被進(jìn)程訪問時(shí),操作系統(tǒng)會(huì)將其從 swap 空間中換入(swap in) ,重新加載回物理內(nèi)存中 ,就像從臨時(shí)存儲(chǔ)區(qū)把貨物重新搬回倉庫使用。

在這個(gè)數(shù)據(jù)交換過程中,內(nèi)核通過維護(hù)一張內(nèi)存映射表來記錄每個(gè)內(nèi)存頁的狀態(tài)和位置信息 。當(dāng)內(nèi)存頁被換出到 swap 空間時(shí),內(nèi)核會(huì)在內(nèi)存映射表中更新該內(nèi)存頁的映射關(guān)系,將其指向 swap 空間中的相應(yīng)位置 ;當(dāng)內(nèi)存頁需要被換入時(shí),內(nèi)核根據(jù)內(nèi)存映射表中的信息,準(zhǔn)確地從 swap 空間中找到對(duì)應(yīng)的內(nèi)存頁數(shù)據(jù),并將其重新映射回物理內(nèi)存 ,確保進(jìn)程能夠正確地訪問到所需的數(shù)據(jù)。

swap 空間的大小需要根據(jù)系統(tǒng)的實(shí)際需求進(jìn)行合理配置 。如果 swap 空間設(shè)置過小,當(dāng)物理內(nèi)存嚴(yán)重不足時(shí),可能無法提供足夠的空間來存儲(chǔ)被換出的內(nèi)存頁數(shù)據(jù),導(dǎo)致系統(tǒng)內(nèi)存耗盡,出現(xiàn)內(nèi)存溢出(Out Of Memory,OOM)錯(cuò)誤 ,進(jìn)而引發(fā)系統(tǒng)崩潰 ;而如果 swap 空間設(shè)置過大,又會(huì)浪費(fèi)磁盤空間資源,因?yàn)榇疟P空間也是有限的 ,而且過多的 swap 空間使用可能會(huì)導(dǎo)致系統(tǒng)性能下降,因?yàn)轭l繁的磁盤 I/O 操作會(huì)增加系統(tǒng)的開銷。

一般來說,對(duì)于桌面系統(tǒng),swap 空間的大小可以設(shè)置為物理內(nèi)存的 1 - 2 倍 ;對(duì)于服務(wù)器系統(tǒng),需要根據(jù)服務(wù)器的具體應(yīng)用場(chǎng)景和內(nèi)存使用情況進(jìn)行更細(xì)致的評(píng)估和調(diào)整 ,例如對(duì)于內(nèi)存需求較大的數(shù)據(jù)庫服務(wù)器,可能需要設(shè)置更大的 swap 空間 ,以應(yīng)對(duì)內(nèi)存突發(fā)緊張的情況。

五、Linux 動(dòng)態(tài)內(nèi)存管理機(jī)制的特點(diǎn)與優(yōu)勢(shì)

5.1 靈活性與高效性

Linux 動(dòng)態(tài)內(nèi)存管理機(jī)制的靈活性和高效性體現(xiàn)在多個(gè)關(guān)鍵方面,為系統(tǒng)的穩(wěn)定運(yùn)行和高性能表現(xiàn)提供了有力支撐。

從動(dòng)態(tài)分配與回收策略來看,Linux 能夠在程序運(yùn)行時(shí),根據(jù)實(shí)際需求動(dòng)態(tài)地分配和回收內(nèi)存 。當(dāng)程序需要新的內(nèi)存空間時(shí),內(nèi)存管理機(jī)制可以迅速響應(yīng),從內(nèi)存池中分配合適大小的內(nèi)存塊給程序使用 ;當(dāng)程序不再需要某些內(nèi)存時(shí),又能及時(shí)將其回收,重新納入內(nèi)存池,供其他程序或本程序后續(xù)使用 。這種根據(jù)需求實(shí)時(shí)調(diào)整內(nèi)存分配的方式,避免了靜態(tài)內(nèi)存分配中可能出現(xiàn)的內(nèi)存浪費(fèi)或不足問題 。例如,在一個(gè)實(shí)時(shí)數(shù)據(jù)處理程序中,隨著數(shù)據(jù)量的動(dòng)態(tài)變化,程序?qū)?nèi)存的需求也會(huì)不斷改變 。Linux 動(dòng)態(tài)內(nèi)存管理機(jī)制可以在數(shù)據(jù)量增大時(shí),及時(shí)為程序分配更多的內(nèi)存來存儲(chǔ)和處理數(shù)據(jù) ;當(dāng)數(shù)據(jù)處理完成,數(shù)據(jù)量減少時(shí),又能回收多余的內(nèi)存,使得這些內(nèi)存可以被其他更需要的程序使用 ,大大提高了內(nèi)存的使用效率,確保系統(tǒng)資源得到充分利用。

在內(nèi)存分配粒度上,Linux 支持多種不同大小的內(nèi)存分配 。無論是極小的內(nèi)存塊,用于存儲(chǔ)簡(jiǎn)單的變量或小型結(jié)構(gòu)體 ,還是極大的內(nèi)存塊,滿足大型數(shù)據(jù)庫、圖形渲染等對(duì)內(nèi)存需求巨大的應(yīng)用場(chǎng)景 ,Linux 都能靈活應(yīng)對(duì) 。通過分頁機(jī)制、伙伴系統(tǒng)以及 slab 分配器等多種內(nèi)存管理組件的協(xié)同工作 ,Linux 可以精確地分配和管理不同粒度的內(nèi)存 。比如,slab 分配器專門用于管理小內(nèi)存對(duì)象的分配,能夠高效地為頻繁分配和釋放小對(duì)象的場(chǎng)景提供支持 ;而伙伴系統(tǒng)則主要負(fù)責(zé)較大內(nèi)存塊的分配和回收,通過合理的內(nèi)存塊劃分和合并策略,減少內(nèi)存碎片的產(chǎn)生,提高內(nèi)存分配的效率 。這種粗細(xì)結(jié)合的內(nèi)存分配粒度,使得 Linux 能夠適應(yīng)各種不同類型應(yīng)用程序的內(nèi)存需求 ,為多樣化的計(jì)算任務(wù)提供了良好的支持。

5.2 內(nèi)存碎片處理策略

在內(nèi)存管理過程中,內(nèi)存碎片是一個(gè)不可避免的問題,它會(huì)嚴(yán)重影響內(nèi)存的分配效率和系統(tǒng)性能 。Linux 系統(tǒng)采用了一系列行之有效的策略來應(yīng)對(duì)內(nèi)存碎片問題,最大限度地減少其對(duì)內(nèi)存分配的負(fù)面影響。

伙伴系統(tǒng)(Buddy System)是 Linux 解決內(nèi)存碎片問題的重要手段之一 。伙伴系統(tǒng)將物理內(nèi)存劃分為不同大小的塊,這些塊的大小按照 2 的冪次方進(jìn)行組織 ,如 4KB、8KB、16KB 等 。當(dāng)有內(nèi)存分配請(qǐng)求時(shí),伙伴系統(tǒng)會(huì)首先尋找大小最接近且能滿足請(qǐng)求的內(nèi)存塊 。如果找不到合適大小的內(nèi)存塊,它會(huì)將更大的內(nèi)存塊分裂成兩個(gè)大小相等的 “伙伴” 塊 ,直到找到滿足需求的內(nèi)存塊 。例如,當(dāng)一個(gè)程序請(qǐng)求分配 8KB 的內(nèi)存時(shí),伙伴系統(tǒng)會(huì)先檢查是否有 8KB 大小的空閑內(nèi)存塊 。如果沒有,它會(huì)查看 16KB 的內(nèi)存塊是否空閑。

若有空閑的 16KB 內(nèi)存塊,就將其分裂成兩個(gè) 8KB 的內(nèi)存塊,一個(gè)分配給程序,另一個(gè)作為空閑塊保留在系統(tǒng)中 。當(dāng)內(nèi)存塊被釋放時(shí),伙伴系統(tǒng)會(huì)檢查其相鄰的內(nèi)存塊是否也是空閑的 。如果相鄰的內(nèi)存塊是空閑的,且大小相同,就將它們合并成一個(gè)更大的內(nèi)存塊 。這種分配和合并機(jī)制有效地減少了外部碎片的產(chǎn)生 ,因?yàn)樗軌蚴箍臻e內(nèi)存盡量集中,便于后續(xù)的內(nèi)存分配。

slab 分配器在減少內(nèi)存碎片方面也發(fā)揮著重要作用 。如前所述,slab 分配器主要用于管理內(nèi)核對(duì)象的小內(nèi)存分配 。它通過為每種類型的對(duì)象創(chuàng)建專門的緩存(Cache) ,預(yù)先分配固定大小的內(nèi)存塊來存儲(chǔ)這些對(duì)象 。當(dāng)有對(duì)象分配請(qǐng)求時(shí),直接從相應(yīng)的緩存中獲取空閑對(duì)象 ;當(dāng)對(duì)象被釋放時(shí),將其重新放回緩存,而不是立即返回給伙伴系統(tǒng) 。這種方式避免了頻繁地向伙伴系統(tǒng)申請(qǐng)和釋放小內(nèi)存塊,減少了內(nèi)存碎片的產(chǎn)生。

以進(jìn)程描述符(task_struct)為例,它是內(nèi)核中頻繁使用的小對(duì)象 。slab 分配器會(huì)為進(jìn)程描述符創(chuàng)建一個(gè)緩存,當(dāng)有新的進(jìn)程創(chuàng)建時(shí),直接從該緩存中分配一個(gè)進(jìn)程描述符對(duì)象 ;當(dāng)進(jìn)程結(jié)束時(shí),將該進(jìn)程描述符對(duì)象放回緩存 。由于緩存中的對(duì)象大小固定且一致,不會(huì)產(chǎn)生內(nèi)部碎片 ,同時(shí)也減少了對(duì)伙伴系統(tǒng)的頻繁訪問,降低了外部碎片產(chǎn)生的可能性。

此外,Linux 還引入了頁遷移(Page Migration)和內(nèi)存碎片整理(Memory Compaction)技術(shù) 。頁遷移技術(shù)允許內(nèi)核將已分配的物理頁從一個(gè)位置移動(dòng)到另一個(gè)位置 ,通過這種方式,可以將分散的內(nèi)存頁重新整理到一起,合并出連續(xù)的空閑區(qū)域 ,從而減少內(nèi)存碎片 。這就好比在一個(gè)書架上,將零散放置的書籍重新整理排列,使空出的空間能夠集中起來,便于放置新的書籍 。內(nèi)存碎片整理則是內(nèi)核定期或按需執(zhí)行的一項(xiàng)操作,它會(huì)將已使用的頁移動(dòng)到一起,騰出連續(xù)的大塊空間 ,主要用于解決外部碎片問題 ,確保系統(tǒng)在需要分配大塊內(nèi)存時(shí)能夠成功分配 。這些技術(shù)的結(jié)合使用,使得 Linux 在面對(duì)內(nèi)存碎片問題時(shí)具有更強(qiáng)的應(yīng)對(duì)能力 ,有效提高了內(nèi)存的利用率和系統(tǒng)的穩(wěn)定性。

責(zé)任編輯:武曉燕 來源: 深度Linux
相關(guān)推薦

2025-03-26 00:00:05

2024-01-26 16:28:28

C++動(dòng)態(tài)內(nèi)存開發(fā)

2022-04-26 06:21:59

編程動(dòng)態(tài)內(nèi)存

2022-01-13 10:30:21

C語言內(nèi)存動(dòng)態(tài)

2012-04-01 14:38:06

Windows Ser虛擬化

2015-11-26 11:02:37

微軟LinuxHyper-V

2018-06-06 08:28:37

Spark內(nèi)存管理

2010-08-18 10:05:28

Hyper-V動(dòng)態(tài)內(nèi)存

2022-01-07 15:10:53

C++動(dòng)態(tài)內(nèi)存

2010-03-02 08:53:59

Windows 8動(dòng)態(tài)內(nèi)存

2010-03-01 09:09:21

Windows 8動(dòng)態(tài)內(nèi)存

2022-03-18 22:39:57

動(dòng)態(tài)內(nèi)存malloc

2011-07-28 10:03:53

Hyper-V動(dòng)態(tài)內(nèi)存

2011-07-20 13:47:14

CC++

2018-12-18 14:37:26

Spark內(nèi)存管理

2019-05-30 11:04:52

內(nèi)存Spark管理

2012-12-25 15:04:07

Windows Ser動(dòng)態(tài)內(nèi)存Hyper-V

2013-10-11 17:32:18

Linux運(yùn)維內(nèi)存管理

2021-05-21 09:25:11

鴻蒙HarmonyOS應(yīng)用

2023-10-18 13:31:00

Linux內(nèi)存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

懂色一区二区三区免费观看| bl动漫在线观看| 精品人妻伦九区久久aaa片| hd国产人妖ts另类视频| 亚洲美女视频| 欧美私人免费视频| 国产精品午夜视频| 久久人人爽人人人人片| 污片在线免费观看| 国产精品一区二区三区四区 | 中文字幕 欧美日韩| 日色在线视频| 国产精品久久久久久久免费软件| 日韩免费福利电影在线观看| 中文字幕欧美人与畜| 中文字幕+乱码+中文乱码www| 亚洲最好看的视频| 日韩欧美中文第一页| 久久久av水蜜桃| 五月天婷婷丁香| 国产精品欧美大片| 天天综合天天做天天综合| 国产欧美一区二区视频| 日韩欧美亚洲一区二区三区| 精品三级av在线导航| 五月激情六月综合| 日韩国产精品毛片| 国产av一区二区三区精品| 亚洲香蕉av| 中文字幕免费精品一区| 福利片一区二区三区| 国产日产一区二区| 国产成人精品一区二| 欧美激情久久久久久| 伊人网综合视频| 国产午夜亚洲精品一级在线| 亚洲午夜电影在线观看| 激情视频在线观看一区二区三区| av中文在线播放| 精品国产1区| 91精品国产综合久久香蕉的特点 | 动漫精品视频| 国产无套内射又大又猛又粗又爽| 国产乱人伦精品一区| 欧美久久久久久久久久| 99国产精品白浆在线观看免费| 欧美一区二区三区成人片在线| 亚洲综合不卡| 视频在线观看一区二区| 久久久久无码精品| 色综合桃花网| 亚洲色图在线视频| 精品国产一区二区三区四区vr| 国产白浆在线观看| 国产麻豆视频一区二区| 亚洲xxxx18| 毛片毛片女人毛片毛片| 成人一二三区| 欧美videos中文字幕| 精品久久久久久无码国产| 成人在线影视| 国产亚洲1区2区3区| 91亚洲永久免费精品| 亚洲黄色三级视频| 午夜亚洲性色视频| 国产999精品久久久| 精品视频久久久久| 手机在线电影一区| 亚洲国产天堂久久综合网| 日韩一区二区三区久久| 欧美a级在线观看| 精品毛片三在线观看| 爱福利视频一区二区| 亚洲综合伊人久久大杳蕉| 久久精品在这里| 国内外成人免费视频| 熟妇人妻一区二区三区四区 | 欧美性猛交xx| 极品国产人妖chinesets亚洲人妖 激情亚洲另类图片区小说区 | 欧美国产一区视频在线观看| 97在线资源站| 91片黄在线观看喷潮| 国产欧美一级| 国产精品久久999| 日本在线免费观看| 日韩精品成人一区二区在线| 韩国三级电影久久久久久| 成年人视频软件| 九九热线有精品视频99| 亚洲国产精品推荐| 少妇av片在线观看| 国产亚洲一卡2卡3卡4卡新区| 精品成人佐山爱一区二区| 五月天激情播播| 激情小说一区| 日韩视频精品在线| 蜜桃av乱码一区二区三区| 91精品精品| 久久精品成人欧美大片| 国产精品麻豆免费版现看视频| 欧美精品成人| 欧美日韩国产va另类| 尤物在线免费视频| 国产日产高清欧美一区二区三区| 国产欧美日韩91| 欧美熟女一区二区| 国产精品进线69影院| 亚洲一区免费看| 91电影在线播放| 欧美国产一区视频在线观看| 隔壁人妻偷人bd中字| 欧美xxxx少妇| 亚洲国产精品一区二区www在线| 国产精品av免费观看| 欧美xxxx性xxxxx高清| 欧美婷婷六月丁香综合色| 视频免费在线观看| 欧美国产91| 91国产一区在线| 中文字幕超碰在线| 国产精品一品二品| 在线看无码的免费网站| 免费福利视频一区二区三区| 在线免费一区三区| 超碰成人在线播放| 免费成人高清在线视频theav| 欧美激情视频播放| 国产叼嘿视频在线观看| 中文字幕亚洲精品在线观看| 免费的av在线| 俺来也官网欧美久久精品| 精品日韩视频在线观看| 大香煮伊手机一区| 美女扒开腿让男人桶爽久久动漫| 久久99精品久久久久久青青91| 亚洲在线观看av| 国产不卡一区视频| 最近免费观看高清韩国日本大全| 欧美日韩卡一| 日韩精品一区二| 久久精品亚洲a| 尹人成人综合网| 国产91久久婷婷一区二区| 欧美 日韩 人妻 高清 中文| 亚洲亚洲精品在线观看| 中文字幕一区二区三区人妻在线视频 | 日本在线视频中文有码| 日韩丝袜情趣美女图片| 91视频啊啊啊| 999亚洲国产精| 国产精品极品在线| www 日韩| 亚洲最快最全在线视频| 91黄色小网站| 你微笑时很美电视剧整集高清不卡| 9.1国产丝袜在线观看| 少妇喷水在线观看| 欧美性少妇18aaaa视频| 国产精品免费无码| 久久99精品国产.久久久久| 国产偷国产偷亚洲高清97cao| 羞羞电影在线观看www| 欧美成人福利视频| 色网站在线播放| 久久久久久久久岛国免费| 九一精品在线观看| 免费成人三级| 风间由美性色一区二区三区四区 | 国产熟女一区二区丰满| aa级大片欧美| 一区二区免费在线视频| www久久久| 亚洲网址你懂得| 国产午夜激情视频| 久久人人爽人人爽| 日韩黄色短视频| 伊人成综合网伊人222| 国产极品jizzhd欧美| 天天摸天天干天天操| 色系网站成人免费| 中国极品少妇videossexhd| 国产精品婷婷| 一本一本a久久| 99久久香蕉| 日韩视频欧美视频| 亚洲欧美另类日韩| 亚洲精品ww久久久久久p站| 一女二男3p波多野结衣| 亚洲二区三区不卡| 久久精品99久久| 24小时成人在线视频| 97超级碰碰碰久久久| 色欧美激情视频在线| 在线精品视频一区二区| 999精品视频在线观看播放| 成人h动漫精品| 美女日批免费视频| 成午夜精品一区二区三区软件| 青青草成人在线| 日本大片在线观看| 91精品蜜臀在线一区尤物| 国产精品视频一区在线观看| 成人av资源在线观看| www.涩涩涩| 欧美hd在线| 久久久久se| 日韩免费一级| 欧美丰满老妇厨房牲生活| 美丽的姑娘在线观看免费动漫| 色综合天天综合网国产成人综合天| 国产喷水在线观看| 国产亚洲一区二区三区| youjizz.com日本| 亚洲久久成人| 蜜桃网站成人| 91成人抖音| 久久精品电影一区二区| 欧美在线观看在线观看| 精品国产凹凸成av人导航| 国产精品久久久久久久一区二区| 亚洲男女一区二区三区| 少妇愉情理伦片bd| 伊人久久亚洲热| 中文字幕在线乱| 日韩久久电影| 亚洲最大的免费| 日本在线视频一区二区| 久热精品视频在线观看一区| 国产亲伦免费视频播放| 欧美性大战久久| 波多野结衣电影在线播放| 亚洲欧洲99久久| www.99热| 亚洲国产精品精华液2区45| 伊人影院综合在线| 丝袜美腿亚洲一区二区图片| 综合色婷婷一区二区亚洲欧美国产| 免费av一区| 日韩福利一区二区三区| 日本一区二区三区视频在线看 | 久久久久999| 顶级网黄在线播放| 成人444kkkk在线观看| 黄网址在线观看| 久久国产色av| 欧美女子与性| 日韩精品在线播放| 国产一区二区小视频| 欧美中文字幕久久| 真实新婚偷拍xxxxx| 欧美色涩在线第一页| 日本熟伦人妇xxxx| 黄色精品一区二区| 国产手机在线视频| 欧美色欧美亚洲高清在线视频| 国产性猛交╳xxx乱大交| 色噜噜狠狠色综合欧洲selulu| 天堂网avav| 91在线免费视频观看| 午夜啪啪小视频| 国产一区二区三区香蕉| 日日碰狠狠躁久久躁婷婷| 久久精品二区三区| 国产精品三级一区二区| 欧美精品观看| 3d动漫一区二区三区| 噜噜爱69成人精品| 午夜久久福利视频| 成人性生交大片免费看中文网站| 孩娇小videos精品| 国产麻豆日韩欧美久久| 少妇被狂c下部羞羞漫画| 国产视频一区二区在线| 欧美一级特黄高清视频| 亚洲成在线观看| 日本中文字幕久久| 欧美精品v日韩精品v韩国精品v| 国内精品国产成人国产三级| 亚洲精品一区二区三区不| 日本中文在线观看| 久久久久久97| 四虎亚洲精品| 欧美在线视频a| 在线观看欧美| 你懂的网址一区二区三区| 欧美高清在线| 国产乱子伦农村叉叉叉| 韩国av一区| 91精品国产吴梦梦| 亚洲伦理精品| 做a视频在线观看| 99久久久免费精品国产一区二区| 国产综合精品久久久久成人av| 2021中文字幕一区亚洲| a一级免费视频| 天天色天天操综合| 国产精品老熟女视频一区二区| 亚洲国产日韩欧美在线99| 日本免费在线观看| 97超碰国产精品女人人人爽| 亚洲乱码一区二区三区在线观看| 免费涩涩18网站入口| 国产iv一区二区三区| 久久久久亚洲av无码a片| 亚洲图片一区二区| 一级特黄色大片| 亚洲毛茸茸少妇高潮呻吟| 国产av无码专区亚洲av| 亚洲人a成www在线影院| 国产三级视频在线| 亚洲新声在线观看| 欧美人与性动交α欧美精品济南到| 国产精品第8页| 三级精品视频| 无码免费一区二区三区免费播放 | 亚洲精品在线免费| 精品久久综合| 男人添女人下面高潮视频| 国产综合色在线视频区| 国产老头和老头xxxx×| 亚洲国产精品精华液2区45| 久久99国产综合精品免费| 日韩三级中文字幕| 黄网站在线免费看| 国产欧美久久久久久| 成人a'v在线播放| 北条麻妃在线视频| 久久只精品国产| 欧美三级午夜理伦| 日韩电影免费观看在线观看| 精品乱码一区二区三四区视频| 一区二区三区四区在线观看视频| 欧美精品hd| 欧美黑人性猛交| 日韩欧美激情电影| xxxxxx在线观看| 国产在线播放一区三区四| 91香蕉视频污在线观看| 欧美日韩亚洲高清一区二区| av电影在线网| 国产精品男人爽免费视频1| 成人黄色91| 懂色av粉嫩av蜜臀av| 国产在线播放一区二区三区 | 精品久久久久久| 天天操天天操天天操| 136fldh精品导航福利| 秋霞蜜臀av久久电影网免费| 日韩欧美视频网站| 99久久99精品久久久久久| 六月丁香婷婷综合| 亚洲视频欧美视频| 成人精品高清在线视频| 影音先锋欧美在线| 国产白丝网站精品污在线入口| 国产成人精品av久久| 亚洲国产精品视频在线观看| 超碰aⅴ人人做人人爽欧美| 奇米精品在线| 激情综合自拍| 六十路息与子猛烈交尾| 日本久久一区二区| avtt亚洲| 成人午夜电影免费在线观看| 99在线|亚洲一区二区| 国产毛片久久久久久久| 亚洲国产精品一区二区www在线| 日本激情一区二区三区| 茄子视频成人在线| 色综合五月天| 性猛交╳xxx乱大交| 精品久久久视频| 91精彩视频在线播放| www日韩av| 亚洲精品极品少妇16p| 国内自拍偷拍视频| 欧美性猛交xxxxx水多| 黄色在线论坛| 精品国产综合| 国内精品自线一区二区三区视频| 久久精品一级片| 日韩一级黄色大片| 免费h视频在线观看| 一本色道久久综合亚洲二区三区 | 色女人在线视频| 欧美日韩精品免费观看视一区二区 | 亚洲丁香久久久| 最新黄网在线观看| 黑人另类av| 激情综合色综合久久| 天天做天天爱夜夜爽| 久久久精品电影| 伊人春色之综合网| 久久久久亚洲av无码网站| 在线免费观看视频一区| 欧美韩日亚洲| 亚洲欧美成人一区| 91原创在线视频| 国产ts变态重口人妖hd| 国产精品亚洲美女av网站|