小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linux內(nèi)存管理

 風(fēng)雪夜歸人_95 2014-12-16
內(nèi)存運行機(jī)制
1)linux系統(tǒng)會不時地進(jìn)行頁面交換操作,保持盡可能多的空閑物理內(nèi)存,即使并不需要內(nèi)存,linux會交換出暫時不用的內(nèi)存頁面。

2)內(nèi)核根據(jù)“最近最經(jīng)常使用”算法,僅僅將一些不經(jīng)常使用的頁面文件交換到虛擬內(nèi)存。有時我們會看到這么一個現(xiàn)象:Linux物理內(nèi)存還有很多,但是交換空間也使用了很多。其實,這并不奇怪,例如,一個占用很大內(nèi)存的進(jìn)程運行時,需要耗費很多內(nèi)存資源,此時就會有一些不常用頁面文件被交換到虛擬內(nèi)存中,但后來這個占用很多內(nèi)存資源的進(jìn)程結(jié)束并釋放了很多內(nèi)存時,剛才被交換出去的頁面文件并不會自動的交換進(jìn)物理內(nèi)存,除非有這個必要,那么此刻系統(tǒng)物理內(nèi)存就會空閑很多,同時交換空間也在被使用,就出現(xiàn)了剛才所說的現(xiàn)象了。

3)交換空間的頁面在使用時會首先被交換到物理內(nèi)存,如果此時沒有足夠的物理內(nèi)存來容納這些頁面,它們又會被馬上交換出去,如此以來,虛擬內(nèi)存中可能沒有足夠空間來存儲這些交換頁面,最終會導(dǎo)致Linux出現(xiàn)假死機(jī)、服務(wù)異常等問題,Linux雖然可以在一段時間內(nèi)自行恢復(fù),但是恢復(fù)后的系統(tǒng)已經(jīng)基本不可用了。

內(nèi)存監(jiān)控常用命令
Linux監(jiān)控內(nèi)存最常使用的命令有free、top等。如圖:
 第一行:
total:物理內(nèi)存的總大小
used:已經(jīng)分配的物理內(nèi)存大小
free:空閑的物理內(nèi)存大?。ㄎ幢徊僮飨到y(tǒng)分配)
shared:多個進(jìn)程共享的內(nèi)存大小,主要用于進(jìn)程間的通訊
buffers/cached:共同表示磁盤緩存的大小
第二行Mem:代表物理內(nèi)存使用情況
第三行(-/+ buffers/cached):代表磁盤緩存使用狀態(tài)
第四行:Swap表示交換空間內(nèi)存使用狀態(tài)

        第二行的數(shù)據(jù)實際上是從操作系統(tǒng)的角度來看的。used僅僅代表操作系統(tǒng)已經(jīng)分配的物理內(nèi)存大小,而不一定是已被使用的內(nèi)存大小。例如,一個應(yīng)用申請了1000KB的內(nèi)存,不會立刻全部使用,可能當(dāng)前只使用了600KB的內(nèi)存,剩余的400KB就可以被“借”給操作系統(tǒng)來作為緩存使用。這些就以第二行的buffers和cashed的形式表示出來。
        buffers與cached都是內(nèi)存操作,用來保存系統(tǒng)曾經(jīng)打開過的文件以及文件屬性信息,這樣當(dāng)操作系統(tǒng)需要讀取某些文件時,會首先在buffers與cached內(nèi)存區(qū)查找,如果找到,直接讀出傳送給應(yīng)用程序,如果沒有找到需要數(shù)據(jù),才從磁盤讀取,這就是操作系統(tǒng)的緩存機(jī)制,通過緩存,大大提高了操作系統(tǒng)的性能。但buffers與cached緩沖的內(nèi)容卻是不同的。
           buffers是用來緩沖塊設(shè)備做的,它只記錄文件系統(tǒng)的元數(shù)據(jù)(metadata)以及 tracking in-flight pages,而cached是用來給文件做緩沖。更通俗一點說:buffers主要用來存放目錄里面有什么內(nèi)容,文件的屬性以及權(quán)限等等。而cached直接用來記憶我們打開過的文件和程序。
         Linux會在需要內(nèi)存的時候,或在系統(tǒng)運行逐步推進(jìn)時,將buffers和cached狀態(tài)的內(nèi)存變?yōu)閒ree狀態(tài)的內(nèi)存,以供系統(tǒng)使用。

    第三行的數(shù)據(jù)則是從應(yīng)用程序的角度來看內(nèi)存分配。這里的“-/+”實際上分別指的是兩個部分:
-buffers/cashed  =   used(第二行) - buffers - cached ;   (即當(dāng)前系統(tǒng)所有程序真實使用的物理內(nèi)存大小)
+buffers/cashed = buffers + cached;    (暫時借給系統(tǒng)作為緩沖區(qū)的內(nèi)存大?。?。
       從上面的論述也可以看出,第三行的free對應(yīng)的一欄實際上是應(yīng)用程序可以使用的內(nèi)存大小,它的值 = free(第二行)+ buffers(第二行) + cached(第二行)。

       如果那些“借給”系統(tǒng)內(nèi)存的程序需要“借出去”的內(nèi)存,則從第二行的free一欄分給該程序。如果有必要的話,就會從buffers/cashed中釋放內(nèi)存,同時將釋放內(nèi)存中的數(shù)據(jù)寫回到硬盤中。如果連buffers/cashed也沒有了,則從硬盤處借,分配SWAP空間。
      你也可以通過命令行強(qiáng)制要求系統(tǒng)歸還這些內(nèi)存,命令如下:
      echo 3 > /proc/sys/vm/drop_caches     (3代表釋放所有bufferes/cashed能釋放的空間)
      不過你需要root權(quán)限?,F(xiàn)象如圖:

 可以看見buffers/cashed兩個部分的空間大大縮小。

內(nèi)存管理
內(nèi)存管理的目標(biāo)是提供一種方法,為實現(xiàn)各種目的而在各個用戶之間實現(xiàn)內(nèi)存共享。內(nèi)存管理方法應(yīng)該實現(xiàn)以下兩個功能:
1)最小化管理內(nèi)存所需的時間
2)最大化用于一般應(yīng)用的可用內(nèi)存(最小化管理開銷)


內(nèi)存管理實際上是一種關(guān)于權(quán)衡的零和游戲。您可以開發(fā)一種使用少量內(nèi)存進(jìn)行管理的算法,但是要花費更多時間來管理可用內(nèi)存。也可以開發(fā)一個算法來有效地管理內(nèi)存,但卻要使用更多的內(nèi)存。最終,特定應(yīng)用程序的需求將促使對這種權(quán)衡作出選擇。

每個內(nèi)存管理器都使用了一種基于堆的分配策略。在這種方法中,大塊內(nèi)存(稱為 堆)用來為用戶定義的目的提供內(nèi)存。當(dāng)用戶需要一塊內(nèi)存時,就請求給自己分配一定大小的內(nèi)存。堆管理器會查看可用內(nèi)存的情況(使用特定算法)并返回一塊內(nèi)存。搜索過程中使用的一些算法有 first-fit(在堆中搜索到的第一個滿足請求的內(nèi)存塊)和 best-fit(使用堆中滿足請求的最合適的內(nèi)存塊)。當(dāng)用戶使用完內(nèi)存后,就將內(nèi)存返回給堆。(注意 :這里的堆和數(shù)據(jù)結(jié)構(gòu)中的堆不是一個概念

這種基于堆的分配策略的根本問題是碎片(fragmentation)。當(dāng)內(nèi)存塊被分配后,它們會以不同的順序在不同的時間返回。這樣會在堆中留下一些洞,需要花一些時間才能有效地管理空閑內(nèi)存。這種算法通常具有較高的內(nèi)存使用效率(分配需要的內(nèi)存),但是卻需要花費更多時間來對堆進(jìn)行管理。

另外一種方法稱為 buddy memory allocation,是一種更快的內(nèi)存分配技術(shù),它將內(nèi)存劃分為 2 的冪次方個分區(qū),并使用 best-fit 方法來分配內(nèi)存請求。當(dāng)用戶釋放內(nèi)存時,就會檢查 buddy 塊,查看其相鄰的內(nèi)存塊是否也已經(jīng)被釋放。如果是的話,將合并內(nèi)存塊以最小化內(nèi)存碎片。這個算法的時間效率更高,但是由于使用 best-fit 方法的緣故,會產(chǎn)生內(nèi)存浪費。

Slab分配器
     Linux 所使用的 slab 分配器的基礎(chǔ)是 Jeff Bonwick 為 SunOS 操作系統(tǒng)首次引入的一種算法。
       最高層是cache_chain,這是一個slab緩存的連接列表,這對于best-fit算法非常有用,可以用來查找最適合所需要的分配大小的緩存(遍歷列表)。cache_chain每個元素都是一個kmem_cache結(jié)構(gòu)的引用,它定義了一個要管理的給定大小的對象池。
每個緩存都包含一個slabs列表,存在三種slab:slabs_full、slabs_patial、slabs_empty.
    由于對象是從 slab 中進(jìn)行分配和釋放的,因此單個 slab 可以在 slab 列表之間進(jìn)行移動。例如,當(dāng)一個 slab 中的所有對象都被使用完時,就從 slabs_partial 列表中移動到 slabs_full 列表中。當(dāng)一個 slab 完全被分配并且有對象被釋放后,就從 slabs_full 列表移動到 slabs_partial 列表。當(dāng)所有對象都被釋放后,就從 slabs_partial 列表移動到 slabs_empty 列表.

內(nèi)存分配
回收目標(biāo)
    不是所有的物理內(nèi)存都可以參與回收的,一般內(nèi)核代碼段、數(shù)據(jù)段、內(nèi)核kmalloc()出來的內(nèi)存,內(nèi)核線程占用的內(nèi)存都是不可以回收的,除此之外的內(nèi)存都是回收的對象。回收的內(nèi)存主要是由用戶態(tài)進(jìn)程占用的內(nèi)存和內(nèi)核自己在運行時所使用的一些內(nèi)存組成。用戶態(tài)進(jìn)程占用的內(nèi)存主要是我們常見的進(jìn)程代碼段,數(shù)據(jù)段,堆棧等,內(nèi)核運行使用的內(nèi)存主要是磁盤高速緩存(如索引節(jié)點,目錄項高速緩存),頁面高速緩存(訪問文件時系統(tǒng)生成的頁面cache),mmap()文件時所用的有名映射所使用的物理內(nèi)存。

 回收時機(jī)
    1)內(nèi)存緊缺回收:grow_buffers()無法獲取緩沖區(qū)頁,alloc_page_buffers()無法獲取頁臨時緩沖區(qū)首部,__alloc_pages()無法再給定的內(nèi)存區(qū)分配一組連續(xù)頁框。
    2)周期回收:必要時,激活相應(yīng)內(nèi)核線程執(zhí)行內(nèi)存回收算法:kswapd()內(nèi)核線程,檢查某個內(nèi)存管理區(qū)的空閑頁框數(shù)是否已低于pages_high值的標(biāo)高。events內(nèi)核線程,一個工作者線程,回收位于高速內(nèi)存緩存中的所有空閑的slab。 

  回收的分類
    主要回收兩類內(nèi)存:最近最少使用內(nèi)存以及高速內(nèi)存緩存中空閑的slab。前者主要包括用戶態(tài)進(jìn)程的代碼段,數(shù)據(jù)段,堆棧,文件映射內(nèi)存,頁高速內(nèi)存,后者主要包括磁盤高速緩存及一些其他的空閑內(nèi)存高速緩存。

內(nèi)存緊缺回收及短期回收
    主要調(diào)用try_to_free_pages(),該函數(shù)會執(zhí)行一個循環(huán),按照優(yōu)先級從12到0依次調(diào)用shrink_cashes(),shrink_slabs()來回收頁面,直到回收至少32個內(nèi)存頁面。
    shrink_caches():調(diào)用shrink_zone()對傳入的zone鏈表中的每個zone,進(jìn)行l(wèi)ru上面的頁面回收。
    shrink_slab():對磁盤索引節(jié)點cache和目錄項索引節(jié)點等磁盤高速緩存進(jìn)行回收,由于磁盤索引節(jié)點和目錄項索引節(jié)點都是從slab高速緩存中分配的,這樣就會導(dǎo)致空閑slab的產(chǎn)生,空閑slab后續(xù)會在周期性回收的cache_reap工作隊列中被回收。估計也就是因為最終會清零空閑slab,才會起這么一個函數(shù)名。^_^
    shrink_zone():對內(nèi)存管理區(qū)上的lru鏈表中的非活躍頁面進(jìn)行回收,在非活躍頁面不足的時候,調(diào)用refill_inactive_zone()對lru上的inactive鏈表補(bǔ)充非活躍頁面,同時shrink_zone()調(diào)用shrink_cache()來進(jìn)行頁面的回收,該函數(shù)的具體解析可以參照下面的源碼淺析。
    shrink_list():該輔助函數(shù)在shrink_cache()中被調(diào)用,該函數(shù)對在shrink_cache()中傳入的非活躍page列表進(jìn)行遍歷,對每個頁面進(jìn)行回收工作,該函數(shù)的具體解析可以參考下面的源碼解析。
    refill_inactie_zone():該輔助函數(shù)根據(jù)一定的規(guī)則將處于lru active鏈表上的活躍頁面移動到inactive鏈表上,以補(bǔ)充可以回收的頁面,在lru鏈表里有兩類頁,一類是屬于用戶態(tài)空間的頁,比如用戶態(tài)進(jìn)程的代碼段,數(shù)據(jù)段,一類是在頁高速緩存中的頁,系統(tǒng)為了降低對應(yīng)用程序的影響,將要優(yōu)先將頁高速緩存頁進(jìn)行回收,同時為了系統(tǒng)整體性能也會適當(dāng)回收用戶態(tài)進(jìn)程頁。




    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多