溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Linux中內(nèi)存管理的案例分析

發(fā)布時(shí)間:2020-11-18 11:31:36 來源:億速云 閱讀:152 作者:小新 欄目:建站服務(wù)器

小編給大家分享一下Linux中內(nèi)存管理的案例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

在linux下,使用top,vmstat,free等命令查看系統(tǒng)或者進(jìn)程的內(nèi)存使用情況時(shí),經(jīng)??吹絙uff/cache memeory,swap,avail Mem等,他們都代表什么意思呢?這篇文章將來聊一聊Linux下的內(nèi)存管理并解答這個(gè)問題。

討論Linux下的內(nèi)存管理其實(shí)就是討論Linux下虛擬內(nèi)存的實(shí)現(xiàn)方式,本人不是內(nèi)核專家,所以這篇文章只會(huì)介紹一些概念性的東西,不會(huì)深入實(shí)現(xiàn)細(xì)節(jié),有些地方描述的有可能不精確。

在早些時(shí)候,物理內(nèi)存比較有限,人們希望程序可以使用的內(nèi)存空間能超過實(shí)際物理內(nèi)存,于是出現(xiàn)了虛擬內(nèi)存的概念,不過隨著時(shí)間的推移,虛擬內(nèi)存的意義已經(jīng)遠(yuǎn)遠(yuǎn)的超過了最初的想法。

一、虛擬內(nèi)存

虛擬內(nèi)存是Linux管理內(nèi)存的一種技術(shù)。它使得每個(gè)應(yīng)用程序都認(rèn)為自己擁有獨(dú)立且連續(xù)的可用的內(nèi)存空間(一段連續(xù)完整的地址空間),而實(shí)際上,它通常是被映射到多個(gè)物理內(nèi)存段,還有部分暫時(shí)存儲(chǔ)在外部磁盤存儲(chǔ)器上,在需要時(shí)再加載到內(nèi)存中來。

每個(gè)進(jìn)程所能使用的虛擬地址大小和CPU位數(shù)有關(guān),在32位的系統(tǒng)上,虛擬地址空間大小是4G,在64位系統(tǒng)上,是2^64=?(算不過來了)。而實(shí)際的物理內(nèi)存可能遠(yuǎn)遠(yuǎn)小于虛擬地址空間的大小。

虛擬地址和進(jìn)程息息相關(guān),不同進(jìn)程里的同一個(gè)虛擬地址指向的物理地址不一定一樣,所以離開進(jìn)程談虛擬地址沒有任何意義。

注意:網(wǎng)上很多文章將虛擬內(nèi)存等同于交換空間,其實(shí)描述不夠嚴(yán)謹(jǐn),交換空間只是虛擬內(nèi)存這張大藍(lán)圖中的一部分。

二、虛擬內(nèi)存和物理內(nèi)存的關(guān)系

下面這張表很直觀的表述了它們之間的關(guān)系

  進(jìn)程X                                                                      進(jìn)程Y
+-------+                                                                  +-------+
| VPFN7 |--+                                                               | VPFN7 |
+-------+  |       進(jìn)程X的                                 進(jìn)程Y的           +-------+
| VPFN6 |  |      Page Table                              Page Table     +-| VPFN6 |
+-------+  |      +------+                                +------+       | +-------+
| VPFN5 |  +----->| .... |---+                    +-------| .... |<---+  | | VPFN5 |
+-------+         +------+   |        +------+    |       +------+    |  | +-------+
| VPFN4 |    +--->| .... |---+-+      | PFN4 |    |       | .... |    |  | | VPFN4 |
+-------+    |    +------+   | |      +------+    |       +------+    |  | +-------+
| VPFN3 |--+ |    | .... |   | | +--->| PFN3 |<---+  +----| .... |<---+--+ | VPFN3 |
+-------+  | |    +------+   | | |    +------+       |    +------+    |    +-------+
| VPFN2 |  +-+--->| .... |---+-+-+    | PFN2 |<------+    | .... |    |    | VPFN2 |
+-------+    |    +------+   | |      +------+            +------+    |    +-------+
| VPFN1 |    |               | +----->| FPN1 |                        +----| VPFN1 |
+-------+    |               |        +------+                             +-------+
| VPFN0 |----+               +------->| PFN0 |                             | VPFN0 |
+-------+                             +------+                             +-------+
 虛擬內(nèi)存                               物理內(nèi)存                               虛擬內(nèi)存


PFN(the page frame number): 頁編號(hào)

當(dāng)進(jìn)程執(zhí)行一個(gè)程序時(shí),需要先從先內(nèi)存中讀取該進(jìn)程的指令,然后執(zhí)行,獲取指令時(shí)用到的就是虛擬地址,這個(gè)地址是程序鏈接時(shí)確定的(內(nèi)核加載并初始化進(jìn)程時(shí)會(huì)調(diào)整動(dòng)態(tài)庫(kù)的地址范圍),為了獲取到實(shí)際的數(shù)據(jù),CPU需要將虛擬地址轉(zhuǎn)換成物理地址,CPU轉(zhuǎn)換地址時(shí)需要用到進(jìn)程的page table,而page table里面的數(shù)據(jù)由操作系統(tǒng)維護(hù)。

注意:Linux內(nèi)核代碼訪問內(nèi)存時(shí)用的都是實(shí)際的物理地址,所以不存在虛擬地址到物理地址的轉(zhuǎn)換,只有應(yīng)用層程序才需要。

為了轉(zhuǎn)換方便,Linux將虛擬內(nèi)存和物理內(nèi)存都拆分為固定大小的頁,x86的系統(tǒng)一般內(nèi)存頁大小是4K,每個(gè)頁都會(huì)分配一個(gè)唯一的編號(hào),這就是頁編號(hào)(PFN).

從上面的圖中可以看出,虛擬內(nèi)存和物理內(nèi)存的page之間通過page table進(jìn)行映射。進(jìn)程X和Y的虛擬內(nèi)存是相互獨(dú)立的,且page table也是獨(dú)立的,它們之間共享物理內(nèi)存。進(jìn)程可以隨便訪問自己的虛擬地址空間,而page table和物理內(nèi)存由內(nèi)核維護(hù)。當(dāng)進(jìn)程需要訪問內(nèi)存時(shí),CPU會(huì)根據(jù)進(jìn)程的page table將虛擬地址翻譯成物理地址,然后進(jìn)行訪問。

注意:并不是每個(gè)虛擬地址空間的page都有對(duì)應(yīng)的Page Table相關(guān)聯(lián),只有虛擬地址被分配給進(jìn)程后,也即進(jìn)程調(diào)用類似malloc函數(shù)之后,系統(tǒng)才會(huì)為相應(yīng)的虛擬地址在Page Table中添加記錄,如果進(jìn)程訪問一個(gè)沒有和Page Table關(guān)聯(lián)的虛擬地址,系統(tǒng)將會(huì)拋出SIGSEGV信號(hào),導(dǎo)致進(jìn)程退出,這也是為什么我們?cè)L問野指針時(shí)會(huì)經(jīng)常出現(xiàn)segmentfault的原因。換句話說,雖然每個(gè)進(jìn)程都有4G(32位系統(tǒng))的虛擬地址空間,但只有向系統(tǒng)申請(qǐng)了的那些地址空間才能用,訪問未分配的地址空間將會(huì)出segmentfault錯(cuò)誤。Linux會(huì)將虛擬地址0不映射到任何地方,這樣我們?cè)L問空指針就一定會(huì)報(bào)segmentfault錯(cuò)誤。

三、虛擬內(nèi)存的優(yōu)點(diǎn)

 ● 更大的地址空間:并且是連續(xù)的,使得程序編寫、鏈接更加簡(jiǎn)單

 ● 進(jìn)程隔離:不同進(jìn)程的虛擬地址之間沒有關(guān)系,所以一個(gè)進(jìn)程的操作不會(huì)對(duì)其它進(jìn)程造成影響

 ● 數(shù)據(jù)保護(hù):每塊虛擬內(nèi)存都有相應(yīng)的讀寫屬性,這樣就能保護(hù)程序的代碼段不被修改,數(shù)據(jù)塊不能被執(zhí)行等,增加了系統(tǒng)的安全性

 ● 內(nèi)存映射:有了虛擬內(nèi)存之后,可以直接映射磁盤上的文件(可執(zhí)行文件或動(dòng)態(tài)庫(kù))到虛擬地址空間,這樣可以做到物理內(nèi)存延時(shí)分配,只有在需要讀相應(yīng)的文件的時(shí)候,才將它真正的從磁盤上加載到內(nèi)存中來,而在內(nèi)存吃緊的時(shí)候又可以將這部分內(nèi)存清空掉,提高物理內(nèi)存利用效率,并且所有這些對(duì)應(yīng)用程序來說是都透明的

 ● 共享內(nèi)存:比如動(dòng)態(tài)庫(kù),只要在內(nèi)存中存儲(chǔ)一份就可以了,然后將它映射到不同進(jìn)程的虛擬地址空間中,讓進(jìn)程覺得自己獨(dú)占了這個(gè)文件。進(jìn)程間的內(nèi)存共享也可以通過映射同一塊物理內(nèi)存到進(jìn)程的不同虛擬地址空間來實(shí)現(xiàn)共享

 ● 物理內(nèi)存管理:物理地址空間全部由操作系統(tǒng)管理,進(jìn)程無法直接分配和回收,從而系統(tǒng)可以更好的利用內(nèi)存,平衡進(jìn)程間對(duì)內(nèi)存的需求

 ● 其它:有了虛擬地址空間后,交換空間和COW(copy on write)等功能都能很方便的實(shí)現(xiàn)

四、page table

page table可以簡(jiǎn)單的理解為一個(gè)memory mapping的鏈表(當(dāng)然實(shí)際結(jié)構(gòu)很復(fù)雜),里面的每個(gè)memory mapping都將一塊虛擬地址映射到一個(gè)特定的資源(物理內(nèi)存或者外部存儲(chǔ)空間)。每個(gè)進(jìn)程擁有自己的page table,和其它進(jìn)程的page table沒有關(guān)系。

五、memory mapping

每個(gè)memory mapping就是對(duì)一段虛擬內(nèi)存的描述,包括虛擬地址的起始位置,長(zhǎng)度,權(quán)限(比如這段內(nèi)存里的數(shù)據(jù)是否可讀、寫、執(zhí)行), 以及關(guān)聯(lián)的資源(如物理內(nèi)存page,swap空間上的page,磁盤上的文件內(nèi)容等)。

當(dāng)進(jìn)程申請(qǐng)內(nèi)存時(shí),系統(tǒng)將返回虛擬內(nèi)存地址,同時(shí)為相應(yīng)的虛擬內(nèi)存創(chuàng)建memory mapping并將它放入page table,但這時(shí)系統(tǒng)不一定會(huì)分配相應(yīng)的物理內(nèi)存,系統(tǒng)一般會(huì)在進(jìn)程真正訪問這段內(nèi)存的時(shí)候才會(huì)分配物理內(nèi)存并關(guān)聯(lián)到相應(yīng)的memory mapping,這就是所謂的延時(shí)分配/按需分配。

每個(gè)memory mapping都有一個(gè)標(biāo)記,用來表示所關(guān)聯(lián)的物理資源類型,一般分兩大類,那就是anonymous和file backed,在這兩大類中,又分了一些小類,比如anonymous下面有更具體的shared和copy on write類型, file backed下面有更具體的device backed類型。下面是每個(gè)類型所代表的意思:

file backed

這種類型表示memory mapping對(duì)應(yīng)的物理資源存放在磁盤上的文件中,它所包含的信息包括文件的位置、offset、rwx權(quán)限等。

當(dāng)進(jìn)程第一次訪問對(duì)應(yīng)的虛擬page的時(shí)候,由于在memory mapping中找不到對(duì)應(yīng)的物理內(nèi)存,CPU會(huì)報(bào)page fault中斷,然后操作系統(tǒng)就會(huì)處理這個(gè)中斷并將文件的內(nèi)容加載到物理內(nèi)存中,然后更新memory mapping,這樣下次CPU就能訪問這塊虛擬地址了。以這種方式加載到內(nèi)存的數(shù)據(jù)一般都會(huì)放到page cache中,關(guān)于page cache會(huì)在后面介紹到.

一般程序的可執(zhí)行文件,動(dòng)態(tài)庫(kù)都是以這種方式映射到進(jìn)程的虛擬地址空間的。

device backed

和file backed類似,只是后端映射到了磁盤的物理地址,比如當(dāng)物理內(nèi)存被swap out后,將被標(biāo)記為device backed。

anonymous

程序自己用到的數(shù)據(jù)段和堆??臻g,以及通過mmap分配的共享內(nèi)存,它們?cè)诖疟P上找不到對(duì)應(yīng)的文件,所以這部分內(nèi)存頁被叫做anonymous page。anonymous page和file backed最大的差別是當(dāng)內(nèi)存吃緊時(shí),系統(tǒng)會(huì)直接刪除掉file backed對(duì)應(yīng)的物理內(nèi)存,因?yàn)橄麓涡枰臅r(shí)候還能從磁盤加載到內(nèi)存,但anonymous page不能被刪除,只能被swap out。

shared

不同進(jìn)程的Page Table里面的多個(gè)memory mapping可以映射到相同的物理地址,通過虛擬地址(不同進(jìn)程里的虛擬地址可能不一樣)可以訪問到相同的內(nèi)容,當(dāng)一個(gè)進(jìn)程里面修改內(nèi)存的內(nèi)容后,在另一個(gè)進(jìn)程中可以立即讀取到。這種方式一般用來實(shí)現(xiàn)進(jìn)程間高速的共享數(shù)據(jù)(如mmap)。當(dāng)標(biāo)記為shared的memory mapping被刪除回收時(shí),需要更新物理page上的引用計(jì)數(shù),便于物理page的計(jì)數(shù)變0后被回收。

copy on write

copy on write基于shared技術(shù),當(dāng)讀這種類型的內(nèi)存時(shí),系統(tǒng)不需要做任何特殊的操作,而當(dāng)要寫這塊內(nèi)存時(shí),系統(tǒng)將會(huì)生成一塊新的內(nèi)存并拷貝原來內(nèi)存中的數(shù)據(jù)到新內(nèi)存中,然后將新內(nèi)存關(guān)聯(lián)到相應(yīng)的memory mapping,然后執(zhí)行寫操作。Linux下很多功能都依賴于copy on write技術(shù)來提高性能,比如fork等。

通過上面的介紹,我們可以簡(jiǎn)單的將內(nèi)存的使用過程總結(jié)如下:

1、進(jìn)程向系統(tǒng)發(fā)出內(nèi)存申請(qǐng)請(qǐng)求

2、系統(tǒng)會(huì)檢查進(jìn)程的虛擬地址空間是否被用完,如果有剩余,給進(jìn)程分配虛擬地址

3、系統(tǒng)為這塊虛擬地址創(chuàng)建相應(yīng)的memory mapping(可能多個(gè)),并將它放進(jìn)該進(jìn)程的page table

4、系統(tǒng)返回虛擬地址給進(jìn)程,進(jìn)程開始訪問該虛擬地址

5、CPU根據(jù)虛擬地址在該進(jìn)程的page table中找到了相應(yīng)的memory mapping,但是該mapping沒有和物理內(nèi)存關(guān)聯(lián),于是產(chǎn)生缺頁中斷

6、操作系統(tǒng)收到缺頁中斷后,分配真正的物理內(nèi)存并將它關(guān)聯(lián)到相應(yīng)的memory mapping

7、中斷處理完成后,CPU就可以訪問該內(nèi)存了

當(dāng)然缺頁中斷不是每次都會(huì)發(fā)生,只有系統(tǒng)覺得有必要延遲分配內(nèi)存的時(shí)候才用的著,也即很多時(shí)候在上面的第3步系統(tǒng)會(huì)分配真正的物理內(nèi)存并和memory mapping關(guān)聯(lián)。

六、其它概念

操作系統(tǒng)只要實(shí)現(xiàn)了虛擬內(nèi)存和物理內(nèi)存之間的映射關(guān)系,就能正常工作了,但要使內(nèi)存訪問更高效,還有很多東西需要考慮,在這里我們可以看看跟內(nèi)存有關(guān)的一些其它概念以及它們的作用。

MMU(Memory Management Unit)

MMU是CPU的一個(gè)用來將進(jìn)程的虛擬地址轉(zhuǎn)換成物理地址的模塊,簡(jiǎn)單點(diǎn)說,這個(gè)模塊的輸入是進(jìn)程的page table和虛擬地址,輸出是物理地址。將虛擬地址轉(zhuǎn)換成物理地址的速度直接影響著系統(tǒng)的速度,所以CPU包含了這個(gè)模塊用來加速。

TLB(Translation Lookaside Buffer)

上面介紹到,MMU的輸入是page table,而page table又存在內(nèi)存里面,跟CPU的cache相比,內(nèi)存的速度很慢,所以為了進(jìn)一步加快虛擬地址到物理地址的轉(zhuǎn)換速度,Linux發(fā)明了TLB,它存在于CPU的L1 cache里面,用來緩存已經(jīng)找到的虛擬地址到物理地址的映射,這樣下次轉(zhuǎn)換前先查一下TLB,如果已經(jīng)在里面了就不需要調(diào)用MMU了.

按需分配物理頁

由于實(shí)際情況下物理內(nèi)存要比虛擬內(nèi)存少很多,所以操作系統(tǒng)必須很小心的分配物理內(nèi)存,以使內(nèi)存的使用率達(dá)到最大化。一個(gè)節(jié)約物理內(nèi)存的辦法就是只加載當(dāng)前正在使用的虛擬page對(duì)應(yīng)的數(shù)據(jù)到內(nèi)存。比如,一個(gè)很大的數(shù)據(jù)庫(kù)程序,如果你只是用了查詢操作,那么負(fù)責(zé)插入刪除等部分的代碼段就沒必要加載到內(nèi)存中,這樣就能節(jié)約很多物理內(nèi)存,這種方法就叫做物理內(nèi)存頁按需分配,也可以稱作延時(shí)加載。

其實(shí)現(xiàn)原理很簡(jiǎn)單,就是當(dāng)CPU訪問一個(gè)虛擬內(nèi)存頁的時(shí)候,如果這個(gè)虛擬內(nèi)存頁對(duì)應(yīng)的數(shù)據(jù)還沒加載到物理內(nèi)存中,則CPU就會(huì)通知操作系統(tǒng)發(fā)生了page fault,然后由操作系統(tǒng)負(fù)責(zé)將數(shù)據(jù)加載進(jìn)物理內(nèi)存。由于將數(shù)據(jù)加載進(jìn)內(nèi)存比較耗時(shí),所以CPU不會(huì)等在那里,而是去調(diào)度其它進(jìn)程,當(dāng)它下次再調(diào)度到該進(jìn)程時(shí),數(shù)據(jù)已經(jīng)在物理內(nèi)存上了。

Linux主要使用這種方式來加載可執(zhí)行文件和動(dòng)態(tài)庫(kù),當(dāng)程序被內(nèi)核開始調(diào)度執(zhí)行時(shí),內(nèi)核將進(jìn)程的可執(zhí)行文件和動(dòng)態(tài)庫(kù)映射到進(jìn)程的虛擬地址空間,并只加載馬上要用到的那小部分?jǐn)?shù)據(jù)到物理內(nèi)存中,其它的部分只有當(dāng)CPU訪問到它們時(shí)才去加載。

交換空間

當(dāng)一個(gè)進(jìn)程需要加載數(shù)據(jù)到物理內(nèi)存中,但實(shí)際的物理內(nèi)存已經(jīng)被用完時(shí),操作系統(tǒng)需要回收一些物理內(nèi)存中的page以滿足當(dāng)前進(jìn)程的需要。

對(duì)于file backed的內(nèi)存數(shù)據(jù),即物理內(nèi)存里面的數(shù)據(jù)來自于磁盤上的文件,那么內(nèi)核將直接將該部分?jǐn)?shù)據(jù)從內(nèi)存中移除掉來釋放出更多的內(nèi)存,當(dāng)下次有進(jìn)程需要訪問這部分?jǐn)?shù)據(jù)時(shí),再將它從磁盤上加載到內(nèi)存中來。但是,如果這部分?jǐn)?shù)據(jù)被修改過且沒被寫入文件,那這部分?jǐn)?shù)據(jù)就變成了臟數(shù)據(jù),臟數(shù)據(jù)不能被直接刪掉,只能被移動(dòng)到交換空間上去。(可執(zhí)行文件和動(dòng)態(tài)庫(kù)文件不會(huì)被修改,但通過mmap+private的方式映射到內(nèi)存的磁盤文件有可能被修改,這種方式映射的內(nèi)存比較特殊,沒修改之前是file backed,修改后但沒有寫回磁盤之前就變成了anonymous的)

對(duì)于anonymous的內(nèi)存數(shù)據(jù),在磁盤上沒有對(duì)應(yīng)的文件,這部分?jǐn)?shù)據(jù)不能直接被刪除,而是被系統(tǒng)移到交換空間上去。交換空間就是磁盤上預(yù)留的一塊特殊空間,被系統(tǒng)用來臨時(shí)存放內(nèi)存中不常被訪問的數(shù)據(jù),當(dāng)下次有進(jìn)程需要訪問交換空間上的數(shù)據(jù)時(shí),系統(tǒng)再將數(shù)據(jù)加載到內(nèi)存中。由于交換空間在磁盤上,所以訪問速度要比內(nèi)存慢很多,頻繁的讀寫交換空間會(huì)帶來性能問題。

關(guān)于swap空間的詳細(xì)介紹請(qǐng)參考Linux交換空間

共享內(nèi)存

有了虛擬內(nèi)存之后,進(jìn)程間共享內(nèi)存變得特別的方便。進(jìn)程所有的內(nèi)存訪問都通過虛擬地址來實(shí)現(xiàn),而每個(gè)進(jìn)程都有自己的page tables。當(dāng)兩個(gè)進(jìn)程共享一塊物理內(nèi)存時(shí),只要將物理內(nèi)存的頁號(hào)映射到兩個(gè)進(jìn)程的page table中就可以了,這樣兩個(gè)進(jìn)程就可以通過不同的虛擬地址來訪問同一塊物理內(nèi)存。

從上面的那個(gè)圖中可以看出,進(jìn)程X和進(jìn)程Y共享了物理內(nèi)存頁P(yáng)FN3,在進(jìn)程X中,PFN3被映射到了VPFN3,而在進(jìn)程Y中,PFN3被映射到了VPFN1,但兩個(gè)進(jìn)程通過不同的虛擬地址訪問到的物理內(nèi)存是同一塊。

訪問控制

page table里面的每條虛擬內(nèi)存到物理內(nèi)存的映射記錄(memory mapping)都包含一份控制信息,當(dāng)進(jìn)程要訪問一塊虛擬內(nèi)存時(shí),系統(tǒng)可以根據(jù)這份控制信息來檢查當(dāng)前的操作是否是合法的。

為什么需要做這個(gè)檢查呢?比如有些內(nèi)存里面放的是程序的可執(zhí)行代碼,那么就不應(yīng)該去修改它;有些內(nèi)存里面存放的是程序運(yùn)行時(shí)用到的數(shù)據(jù),那么這部分內(nèi)存只能被讀寫,不應(yīng)該被執(zhí)行;有些內(nèi)存里面存放的是內(nèi)核的代碼,那么在用戶態(tài)就不應(yīng)該去執(zhí)行它;有了這些檢查之后會(huì)大大增強(qiáng)系統(tǒng)的安全性。

huge pages

由于CPU的cache有限,所以TLB里面緩存的數(shù)據(jù)也有限,而采用了huge page后,由于每頁的內(nèi)存變大(比如由原來的4K變成了4M),雖然TLB里面的紀(jì)錄數(shù)沒變,但這些紀(jì)錄所能覆蓋的地址空間變大,相當(dāng)于同樣大小的TLB里面能緩存的映射范圍變大,從而減少了調(diào)用MMU的次數(shù),加快了虛擬地址到物理地址的轉(zhuǎn)換速度。

Caches

為了提高系統(tǒng)性能,Linux使用了一些跟內(nèi)存管理相關(guān)的cache,并且盡量將空閑的內(nèi)存用于這些cache。這些cache都是系統(tǒng)全局共享的:

  • Buffer Cache
    用來緩沖塊設(shè)備上的數(shù)據(jù),比如磁盤,當(dāng)讀寫塊設(shè)備時(shí),系統(tǒng)會(huì)將相應(yīng)的數(shù)據(jù)存放到這個(gè)cache中,等下次再訪問時(shí),可以直接從cache中拿數(shù)據(jù),從而提高系統(tǒng)效率。它里面的數(shù)據(jù)結(jié)構(gòu)是一個(gè)塊設(shè)備ID和block編號(hào)到具體數(shù)據(jù)的映射,只要根據(jù)塊設(shè)備ID和塊的編號(hào),就能找到相應(yīng)的數(shù)據(jù)。

  • Page Cache
    這個(gè)cache主要用來加快讀寫磁盤上文件的速度。它里面的數(shù)據(jù)結(jié)構(gòu)是文件ID和offset到文件內(nèi)容的映射,根據(jù)文件ID和offset就能找到相應(yīng)的數(shù)據(jù)(這里文件ID可能是inode或者path,本人沒有仔細(xì)去研究)。

從上面的定義可以看出,page cache和buffer cache有重疊的地方,不過實(shí)際情況是buffer cache只緩存page cache不緩存的那部分內(nèi)容,比如磁盤上文件的元數(shù)據(jù)。所以一般情況下和page cache相比,Buffer Cache的大小基本可以忽略不計(jì)。

當(dāng)然,使用cache也有一些不好的地方,比如需要時(shí)間和空間去維護(hù)cache,cache一旦出錯(cuò),整個(gè)系統(tǒng)就掛了。

七、總結(jié)

有了上面介紹的知識(shí),再來看看我們剛開始提出來的問題,以top命令的輸出為例:

KiB Mem :   500192 total,   349264 free,    36328 used,   114600 buff/cache
KiB Swap:   524284 total,   524284 free,        0 used.   433732 avail Mem

KiB Mem代表物理內(nèi)存,KiB Swap代表交換空間,它們的單位都是KiB。

total、used和free沒什么好介紹的,就是總共多少,然后用了多少,還剩多少。

buff/cached代表了buff和cache總共用了多少,buff代表buffer cache占了多少空間,由于它主要用來緩存磁盤上文件的元數(shù)據(jù),所以一般都比較小,跟cache比可以忽略不計(jì);cache代表page cache和其它一些占用空間比較小且大小比較固定的cache的總和,基本上cache就約等于page cache,page cache的準(zhǔn)確值可以通過查看/proc/meminf中的Cached得到。由于page cache是用來緩存磁盤上文件內(nèi)容的,所以占有空間很大,Linux一般會(huì)盡可能多的將空閑物理內(nèi)存用于page cache。

avail Mem表示可用于進(jìn)程下一次分配的物理內(nèi)存數(shù)量,這個(gè)大小一般比free大一點(diǎn),因?yàn)槌薴ree的空間外,系統(tǒng)還能立即釋放出一些空間來。

那么怎么判斷當(dāng)前內(nèi)存使用情況出現(xiàn)了異常呢?有下面幾點(diǎn)供參考:

● Mem free的值比較小,并且buff/cache的值也小
free的值比較少并不一定代表有問題,因?yàn)長(zhǎng)inux會(huì)盡可能多的將內(nèi)存用于page cache,但是如果buff/cache的值也小,就說明內(nèi)存吃緊了,系統(tǒng)沒有足夠多的內(nèi)存用于cache,如果當(dāng)前服務(wù)器部署是一個(gè)需要頻繁的讀寫磁盤的應(yīng)用,如FTP服務(wù)器,那么對(duì)性能的影響將會(huì)非常大。

● Swap used的值比較大,
這種情況比上面的更嚴(yán)重,正常情況下swap應(yīng)該很少被使用,used值比較大說明交換空間被使用的比較多,如果通過vmstat命令看到swap in/out的比較頻繁的話,說明系統(tǒng)內(nèi)存嚴(yán)重不足,整體性能已經(jīng)受到嚴(yán)重影響

以上是Linux中內(nèi)存管理的案例分析的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI