Linux內(nèi)存管理詳解_第1頁(yè)
Linux內(nèi)存管理詳解_第2頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、虛擬地址即使是現(xiàn)代操作系統(tǒng)中,內(nèi)存依然是計(jì)算機(jī)中很寶貴的資源,看看你電腦幾個(gè)T固態(tài)硬盤,再看看內(nèi)存大小就知道了。為了充分利用和管理系統(tǒng)內(nèi)存資源,Linux采用虛擬內(nèi)存管理技術(shù),利用虛擬內(nèi)存技術(shù)讓每個(gè)進(jìn)程都有4GB互不干涉的虛擬地址空間。進(jìn)程初始化分配和操作的都是基于這個(gè)虛擬地址,只有當(dāng)進(jìn)程需要實(shí)際訪問(wèn)內(nèi)存資源的時(shí)候才會(huì)建立虛擬地址和物理地址的映射,調(diào)入物理內(nèi)存頁(yè)。打個(gè)不是很恰當(dāng)?shù)谋确?,這個(gè)原理其實(shí)和現(xiàn)在的某某網(wǎng)盤一樣。假如你的網(wǎng)盤空間是1TB,真以為就一口氣給了你這么大空間嗎?那還是太年輕,都是在你往里面放東西的時(shí)候才給你分配空間,你放多少就分多少實(shí)際空間給你,但你和你朋友看起來(lái)就像大家都擁有

2、1TB空間一樣。虛擬地址的好處o避免用戶直接訪問(wèn)物理內(nèi)存地址,防止一些破壞性操作,保護(hù)操作系統(tǒng)o每個(gè)進(jìn)程都被分配了4GB的虛擬內(nèi)存,用戶程序可使用比實(shí)際物理內(nèi)存更大的地址空間芒程m用戶空間3GB進(jìn)程C用戶空間3GB4GB的進(jìn)程虛擬地址空間被分成兩部分:用戶空間和內(nèi)核空間芒程豈用戶空亙3GB1GB用戶空間內(nèi)核空間物理地址上面章節(jié)我們已經(jīng)知道不管是用戶空間還是內(nèi)核空間,使用的地址都是虛擬地址,當(dāng)需進(jìn)程要實(shí)際訪問(wèn)內(nèi)存的時(shí)候,會(huì)由內(nèi)核的請(qǐng)求分頁(yè)機(jī)制產(chǎn)生缺頁(yè)異常調(diào)入物理內(nèi)存頁(yè)。把虛擬地址轉(zhuǎn)換成內(nèi)存的物理地址,這中間涉及利用MMU內(nèi)存管理單元(MemoryManagementUnit)對(duì)虛擬地址分段和分頁(yè)

3、(段頁(yè)式)地址轉(zhuǎn)換,關(guān)于分段和分頁(yè)的具體流程,這里不再贅述,可以參考任何一本計(jì)算機(jī)組成原理教材描述。aw厲昨段頁(yè)式內(nèi)存管理地址轉(zhuǎn)換Linux內(nèi)核會(huì)將物理內(nèi)存分為3個(gè)管理區(qū),分別是:ZONE_DMADMA內(nèi)存區(qū)域。包含0MB16MB之間的內(nèi)存頁(yè)框,可以由老式基于ISA的設(shè)備通過(guò)DMA使用,直接映射到內(nèi)核的地址空間。ZONE_NORMAL普通內(nèi)存區(qū)域。包含16MB896MB之間的內(nèi)存頁(yè)框,常規(guī)頁(yè)框,直接映射到內(nèi)核的地址空間。ZONE_HIGHMEM高端內(nèi)存區(qū)域。包含896MB以上的內(nèi)存頁(yè)框,不進(jìn)行直接映射,可以通過(guò)永久映射和臨時(shí)映射進(jìn)行這部分內(nèi)存頁(yè)框的訪問(wèn)。物理內(nèi)存區(qū)劃分用戶空間用戶進(jìn)程能訪問(wèn)的是

4、用戶空間,每個(gè)進(jìn)程都有自己獨(dú)立的用戶空間,虛擬地址范圍從從0x00000000至OxBFFFFFFF總?cè)萘?G。用戶進(jìn)程通常只能訪問(wèn)用戶空間的虛擬地址,只有在執(zhí)行內(nèi)陷操作或系統(tǒng)調(diào)用時(shí)才能訪問(wèn)內(nèi)核空間。進(jìn)程與內(nèi)存進(jìn)程(執(zhí)行的程序)占用的用戶空間按照訪問(wèn)屬性一致的地址空間存放在一起的原則,劃分成5個(gè)不同的內(nèi)存區(qū)域。訪問(wèn)屬性指的是“可讀、可寫、可執(zhí)行等。o代碼段代碼段是用來(lái)存放可執(zhí)行文件的操作指令,可執(zhí)行程序在內(nèi)存中的鏡像。代碼段需要防止在運(yùn)行時(shí)被非法修改,所以只準(zhǔn)許讀取操作,它是不可寫的。o數(shù)據(jù)段數(shù)據(jù)段用來(lái)存放可執(zhí)行文件中已初始化全局變量,換句話說(shuō)就是存放程序靜態(tài)分配的變量和全局變量。oBSS段B

5、SS段包含了程序中未初始化的全局變量,在內(nèi)存中bss段全部置零。o堆heap堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減)。o棧stack棧是用戶存放程序臨時(shí)創(chuàng)建的局部變量,也就是函數(shù)中定義的變量(但不包括static聲明的變量,static意味著在數(shù)據(jù)段中存放變量)。除此以外,在函數(shù)被調(diào)用時(shí),其參數(shù)也會(huì)被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會(huì)被存放回棧中。由于棧的先進(jìn)先出特點(diǎn),所以棧特別方

6、便用來(lái)保存/恢復(fù)調(diào)用現(xiàn)場(chǎng)。從這個(gè)意義上講,我們可以把堆??闯梢粋€(gè)寄存、交換臨時(shí)數(shù)據(jù)的內(nèi)存區(qū)。上述幾種內(nèi)存區(qū)域中數(shù)據(jù)段、BSS段、堆通常是被連續(xù)存儲(chǔ)在內(nèi)存中,在位置上是連續(xù)的,而代碼段和棧往往會(huì)被獨(dú)立存放。堆和棧兩個(gè)區(qū)域在i386體系結(jié)構(gòu)中棧向下擴(kuò)展、堆向上擴(kuò)展,相對(duì)而生。你也可以在linux下用size命令查看編譯后程序的各個(gè)內(nèi)存區(qū)域大?。簂emon#size/usr/local/sbin/sshdtextdatabssdechexfilename19245321241242689623638402411c0/usr/local/sbin/sshd內(nèi)核空間在x8632位系統(tǒng)里,Linux內(nèi)核地

7、址空間是指虛擬地址從OxCO000000開始到OxFFFFFFFF為止的高端內(nèi)存地址空間,總計(jì)1G的容量,包括了內(nèi)核鏡像、物理頁(yè)面表、驅(qū)動(dòng)程序等運(yùn)行在內(nèi)核空間直接映射區(qū)直接映射區(qū)DirectMemoryRegion:從內(nèi)核空間起始地址開始,最大896M的內(nèi)核空間地址區(qū)間,為直接內(nèi)存映射區(qū)。直接映射區(qū)的896MB的線性地址直接與物理地址的前896MB進(jìn)行映射,也就是說(shuō)線性地址和分配的物理地址都是連續(xù)的。內(nèi)核地址空間的線性地址0xC0000001所對(duì)應(yīng)的物理地址為0x00000001,它們之間相差一個(gè)偏移量PAGE_OFFSET=0xC0000000該區(qū)域的線性地址和物理地址存在線性轉(zhuǎn)換關(guān)系線性地

8、址二PAGE_OFFSET+物理地址也可以用virt_to_phys()函數(shù)將內(nèi)核虛擬空間中的線性地址轉(zhuǎn)化為物理地址。高端內(nèi)存線性地址空間內(nèi)核空間線性地址從896M到1G的區(qū)間,容量128MB的地址區(qū)間是高端內(nèi)存線性地址空間,為什么叫高端內(nèi)存線性地址空間?下面給你解釋一下:前面已經(jīng)說(shuō)過(guò),內(nèi)核空間的總大小1GB,從內(nèi)核空間起始地址開始的896MB的線性地址可以直接映射到物理地址大小為896MB的地址區(qū)間。所以,內(nèi)核空間拿出了最后的128M地址區(qū)間,劃分成下面三個(gè)高端內(nèi)存映射區(qū),以達(dá)到對(duì)整個(gè)物理地址范圍的尋址。而在64位的系統(tǒng)上就不存在這樣的問(wèn)題了,因?yàn)榭捎玫木€性地址空間遠(yuǎn)大于可安裝的內(nèi)存。動(dòng)態(tài)內(nèi)

9、存映射區(qū)vmallocRegion該區(qū)域由內(nèi)核函數(shù)vmalloc來(lái)分配,特點(diǎn)是:線性空間連續(xù),但是對(duì)應(yīng)的物理地址空間不一定連續(xù)。vmalloc分配的線性地址所對(duì)應(yīng)的物理頁(yè)可能處于低端內(nèi)存,也可能處于高端內(nèi)存。永久內(nèi)存映射區(qū)PersistentKernelMappingRegion該區(qū)域可訪問(wèn)高端內(nèi)存。訪問(wèn)方法是使用alloc_page(_GFP_HIGHMEM)分配高端內(nèi)存頁(yè)或者使用kmap函數(shù)將分配到的高端內(nèi)存映射到該區(qū)域。固定映射區(qū)FixingkernelMappingRegion該區(qū)域和4G的頂端只有4k的隔離帶,其每個(gè)地址項(xiàng)都服務(wù)于特定的用途,如ACPI_BASE等。叵逗疋肓映更區(qū)oS

10、OM-4G永久內(nèi)存映幻區(qū)4MEBKELtt128M的法性世址®壬到物湮地址的奇娠內(nèi)存ZON匚4ORMAL*ZONbDMA8S0M安主保護(hù)因或sr/EiBr.i直接時(shí)摳B-h0SK1內(nèi)核空間物理內(nèi)存映射上面講的有點(diǎn)多,先別著急進(jìn)入下一節(jié),在這之前我們?cè)賮?lái)回顧一下上面所講的內(nèi)容。如果認(rèn)真看完上面的章節(jié),我這里再畫了一張圖,現(xiàn)在你的腦海中應(yīng)該有這樣一個(gè)內(nèi)存管理的全局圖。用戶空問(wèn)3GB3GB內(nèi)樓空巨1GBiasc電口空間$684ME內(nèi)核空間用戶空間全圖用戶空間進(jìn)程的地址管理模型:wm_arem_struet內(nèi)存數(shù)據(jù)結(jié)構(gòu)要讓內(nèi)核管理系統(tǒng)中的虛擬內(nèi)存,必然要從中抽象出內(nèi)存管理數(shù)據(jù)結(jié)構(gòu),內(nèi)存管理操

11、作如分配、釋放等都基于這些數(shù)據(jù)結(jié)構(gòu)操作,這里列舉兩個(gè)管理虛擬內(nèi)存區(qū)域的數(shù)據(jù)結(jié)構(gòu)。用戶空間內(nèi)存數(shù)據(jù)結(jié)構(gòu)在前面進(jìn)程與內(nèi)存章節(jié)我們提到,Linux進(jìn)程可以劃分為5個(gè)不同的內(nèi)存區(qū)域,分別是:代碼段、數(shù)據(jù)段、BSS、堆、棧,內(nèi)核管理這些區(qū)域的方式是,將這些內(nèi)存區(qū)域抽象成vm_area_struet的內(nèi)存管理對(duì)象。vm_area_struet是描述進(jìn)程地址空間的基本管理單元,一個(gè)進(jìn)程往往需要多個(gè)vm_area_struet來(lái)描述它的用戶空間虛擬地址,需要使用鏈表和紅黑樹來(lái)組織各個(gè)vm_area_struet。鏈表用于需要遍歷全部節(jié)點(diǎn)的時(shí)候用,而紅黑樹適用于在地址空間中定位特定內(nèi)存區(qū)域。內(nèi)核為了內(nèi)存區(qū)域上的

12、各種不同操作都能獲得高性能,所以同時(shí)使用了這兩種數(shù)據(jù)結(jié)構(gòu)。內(nèi)核空間動(dòng)態(tài)分配內(nèi)存數(shù)據(jù)結(jié)構(gòu)在內(nèi)核空間章節(jié)我們提到過(guò)動(dòng)態(tài)內(nèi)存映射區(qū),該區(qū)域由內(nèi)核函數(shù)vmalloc來(lái)分配,特點(diǎn)是:線性空間連續(xù),但是對(duì)應(yīng)的物理地址空間不一定連續(xù)。vmalloc分配的線性地址所對(duì)應(yīng)的物理頁(yè)可能處于低端內(nèi)存,也可能處于高端內(nèi)存。vmalloe分配的地址貝V限于vmalloe_start與vmalloe_end之間。每一塊vmalloe分配的內(nèi)核虛擬內(nèi)存都對(duì)應(yīng)一個(gè)vm_struet結(jié)構(gòu)體,不同的內(nèi)核空間虛擬地址之間有4k大小的防越界空閑區(qū)間隔區(qū)。與用戶空間的虛擬地址特性一樣,這些虛擬地址與物理內(nèi)存沒(méi)有簡(jiǎn)單的映射關(guān)系,必須通過(guò)

13、內(nèi)核頁(yè)表才可轉(zhuǎn)換為物理地址或物理頁(yè),它們有可能尚未被映射,當(dāng)發(fā)生缺頁(yè)時(shí)才真正分配物理頁(yè)面。因走刁牢珥肘區(qū)4ME打配地址4KvmsllK対配地lit4KVIHjlllQC舟配他址4ME安主-呉護(hù)區(qū)阪8b/b聶小E96IJvm_structvm_strucfvin_struct動(dòng)態(tài)內(nèi)存映射前面分析了Linux內(nèi)存管理機(jī)制,下面深入學(xué)習(xí)物理內(nèi)存管理和虛擬內(nèi)存分配。通過(guò)前面的學(xué)習(xí)我們知道,程序可沒(méi)這么好騙,任你內(nèi)存管理把虛擬地址空間玩出花來(lái),到最后還是要給程序?qū)崒?shí)在在的物理內(nèi)存,不然程序就要罷工了。所以物理內(nèi)存這么重要的資源一定要好好管理起來(lái)使用(物理內(nèi)存,就是你實(shí)實(shí)在在的內(nèi)存條),那么內(nèi)核是如何管理

14、物理內(nèi)存的呢?物理內(nèi)存管理在Linux系統(tǒng)中通過(guò)分段和分頁(yè)機(jī)制,把物理內(nèi)存劃分4K大小的內(nèi)存頁(yè)P(yáng)age(也稱作頁(yè)框PageFrame),物理內(nèi)存的分配和回收都是基于內(nèi)存頁(yè)進(jìn)行,把物理內(nèi)存分頁(yè)管理的好處大大的。假如系統(tǒng)請(qǐng)求小塊內(nèi)存,可以預(yù)先分配一頁(yè)給它,避免了反復(fù)的申請(qǐng)和釋放小塊內(nèi)存帶來(lái)頻繁的系統(tǒng)開銷。假如系統(tǒng)需要大塊內(nèi)存,則可以用多頁(yè)內(nèi)存拼湊,而不必要求大塊連續(xù)內(nèi)存。你看不管內(nèi)存大小都能收放自如,分頁(yè)機(jī)制多么完美的解決方案!But,理想很豐滿,現(xiàn)實(shí)很骨感。如果就直接這樣把內(nèi)存分頁(yè)使用,不再加額外的管理還是存在一些問(wèn)題,下面我們來(lái)看下,系統(tǒng)在多次分配和釋放物理頁(yè)的時(shí)候會(huì)遇到哪些問(wèn)題。物理頁(yè)管理面

15、臨問(wèn)題物理內(nèi)存頁(yè)分配會(huì)出現(xiàn)外部碎片和內(nèi)部碎片問(wèn)題,所謂的內(nèi)部和外部是針對(duì)頁(yè)框內(nèi)外而言,一個(gè)頁(yè)框內(nèi)的內(nèi)存碎片是內(nèi)部碎片,多個(gè)頁(yè)框間的碎片是外部碎片。外部碎片當(dāng)需要分配大塊內(nèi)存的時(shí)候,要用好幾頁(yè)組合起來(lái)才夠,而系統(tǒng)分配物理內(nèi)存頁(yè)的時(shí)候會(huì)盡量分配連續(xù)的內(nèi)存頁(yè)面,頻繁的分配與回收物理頁(yè)導(dǎo)致大量的小塊內(nèi)存夾雜在已分配頁(yè)面中間,形成外部碎片,舉個(gè)例子:外部碎片內(nèi)部碎片物理內(nèi)存是按頁(yè)來(lái)分配的,這樣當(dāng)實(shí)際只需要很小內(nèi)存的時(shí)候,也會(huì)分配至少是4K大小的頁(yè)面,而內(nèi)核中有很多需要以字節(jié)為單位分配內(nèi)存的場(chǎng)景,這樣本來(lái)只想要幾個(gè)字節(jié)而已卻不得不分配一頁(yè)內(nèi)存,除去用掉的字節(jié)剩下的就形成了內(nèi)部碎片。內(nèi)部碎片頁(yè)面管理算法方法

16、總比困難多,因?yàn)榇嬖谏厦娴倪@些問(wèn)題,聰明的程序員靈機(jī)一動(dòng),引入了頁(yè)面管理算法來(lái)解決上述的碎片問(wèn)題。Buddy(伙伴)分配算法Linux內(nèi)核引入了伙伴系統(tǒng)算法(Buddysystem),什么意思呢?就是把相同大小的頁(yè)框塊用鏈表串起來(lái),頁(yè)框塊就像手拉手的好伙伴,也是這個(gè)算法名字的由來(lái)。具體的,所有的空閑頁(yè)框分組為11個(gè)塊鏈表,每個(gè)塊鏈表分別包含大小為1,2,4,8,16,32,64,128,256,512和1024個(gè)連續(xù)頁(yè)框的頁(yè)框塊。最大可以申請(qǐng)1024個(gè)連續(xù)頁(yè)框,對(duì)應(yīng)4MB大小的連續(xù)內(nèi)存。伙伴系統(tǒng)因?yàn)槿魏握麛?shù)都可以由2'n的和組成,所以總能找到合適大小的內(nèi)存塊分配出去,減少了外部碎片產(chǎn)

17、生。分配實(shí)例比如:我需要申請(qǐng)4個(gè)頁(yè)框,但是長(zhǎng)度為4個(gè)連續(xù)頁(yè)框塊鏈表沒(méi)有空閑的頁(yè)框塊,伙伴系統(tǒng)會(huì)從連續(xù)8個(gè)頁(yè)框塊的鏈表獲取一個(gè),并將其拆分為兩個(gè)連續(xù)4個(gè)頁(yè)框塊,取其中一個(gè),另外一個(gè)放入連續(xù)4個(gè)頁(yè)框塊的空閑鏈表中。釋放的時(shí)候會(huì)檢查,釋放的這幾個(gè)頁(yè)框前后的頁(yè)框是否空閑,能否組成下一級(jí)長(zhǎng)度的塊。命令查看lemon#cat/proc/buddyinfoNode0,zoneDMA10002110113Node0,zoneDMA323198410849404773403021848911806732330Node0,zoneNormal4243837404160354386610121223001slab分

18、配器看到這里你可能會(huì)想,有了伙伴系統(tǒng)這下總可以管理好物理內(nèi)存了吧?不,還不夠,否則就沒(méi)有slab分配器什么事了。那什么是slab分配器呢?一般來(lái)說(shuō),內(nèi)核對(duì)象的生命周期是這樣的:分配內(nèi)存-初始化-釋放內(nèi)存,內(nèi)核中有大量的小對(duì)象,比如文件描述結(jié)構(gòu)對(duì)象、任務(wù)描述結(jié)構(gòu)對(duì)象,如果按照伙伴系統(tǒng)按頁(yè)分配和釋放內(nèi)存,對(duì)小對(duì)象頻繁的執(zhí)行分配內(nèi)存-初始化-釋放內(nèi)存會(huì)非常消耗性能?;锇橄到y(tǒng)分配出去的內(nèi)存還是以頁(yè)框?yàn)閱挝?,而?duì)于內(nèi)核的很多場(chǎng)景都是分配小片內(nèi)存,遠(yuǎn)用不到一頁(yè)內(nèi)存大小的空間。slab分配器,通過(guò)將內(nèi)存按使用對(duì)象不同再劃分成不同大小的空間,應(yīng)用于內(nèi)核對(duì)象的緩存?;锇橄到y(tǒng)和slab不是二選一的關(guān)系,slab內(nèi)

19、存分配器是對(duì)伙伴分配算法的補(bǔ)充。原理對(duì)于每個(gè)內(nèi)核中的相同類型的對(duì)象,如task_struet、file_struet等需要重復(fù)使用的小型內(nèi)核數(shù)據(jù)對(duì)象,都會(huì)有個(gè)slab緩存池,緩存住大量常用的已經(jīng)初始化的對(duì)象,每當(dāng)要申請(qǐng)這種類型的對(duì)象時(shí),就從緩存池的slab列表中分配一個(gè)出去;而當(dāng)要釋放時(shí),將其重新保存在該列表中,而不是直接返回給伙伴系統(tǒng),從而避免內(nèi)部碎片,同時(shí)也大大提高了內(nèi)存分配性能。主要優(yōu)點(diǎn)slab內(nèi)存管理基于內(nèi)核小對(duì)象,不用每次都分配一頁(yè)內(nèi)存,充分利用內(nèi)存空間,避免內(nèi)部碎片。slab對(duì)內(nèi)核中頻繁創(chuàng)建和釋放的小對(duì)象做緩存,重復(fù)利用一些相同的對(duì)象,減少內(nèi)存分配次數(shù)。數(shù)據(jù)結(jié)構(gòu)slab分配器kme

20、m_eaehe是一個(gè)eache_ehain的鏈表組成節(jié)點(diǎn),代表的是個(gè)內(nèi)核中的相同類型的對(duì)象高速緩存,每個(gè)kmem_cache通常是一段連續(xù)的內(nèi)存塊,包含了三種類型的slabs鏈表:slabs_full(完全分配的slab鏈表)slabs_partial(部分分配的slab鏈表)slabs_empty(沒(méi)有被分配對(duì)象的slab鏈表)kmem_eaehe中有個(gè)重要的結(jié)構(gòu)體kmem_list3包含了以上三個(gè)數(shù)據(jù)結(jié)構(gòu)的聲明。st,ul'ttniEE_l.i_st3structllt.hEadslabspartial;3structYtst_headslibs_full;"昇(1寓II

21、宅閑酋mZbJIS述符打slructListhad5labs_"Free;/*Y'?id&*isl.ab!j''士、!unsiqidLongfreezebjectsunsigned.inTfree_limitj1unsignedtntcolour_next;/*er-nodecachec<iLoring:-spinlock._tltst_lock;'.1ul'.airay_cjcb£'*shared;h.Tstmctarray_-cache*alien;an(XtKernodes*/unsigneitLnnqne

22、xt_reap;.-i1intfrtauehtd;-.;tlwi-u-打kmem_list3內(nèi)核源碼slab是slab分配器的最小單位,在實(shí)現(xiàn)上一個(gè)slab由一個(gè)或多個(gè)連續(xù)的物理頁(yè)組成(通常只有一頁(yè))。單個(gè)slab可以在slab鏈表之間移動(dòng),例如如果一個(gè)半滿slabs_partial鏈表被分配了對(duì)象后變滿了,就要從slabs_partial中刪除,同時(shí)插入到全滿slabs_full鏈表中去。內(nèi)核slab對(duì)象的分配過(guò)程是這樣的:1. 如果slabs_partial鏈表還有未分配的空間,分配對(duì)象,若分配之后變滿,移動(dòng)slab到slabs_full鏈表2. 如果slabs_partial鏈表沒(méi)有未分

23、配的空間,進(jìn)入下一步3. 如果slabs_empty鏈表還有未分配的空間,分配對(duì)象,同時(shí)移動(dòng)slab進(jìn)入slabs_partial鏈表4. 如果slabs_empty為空,請(qǐng)求伙伴系統(tǒng)分頁(yè),創(chuàng)建一個(gè)新的空閑slab,按步驟3分配對(duì)象7EElatE_p&rtial5l3bE_enpty-薦三鬧5st'?Ku蠱了三?£lat£_pQr:ial育空麗甜?SlEti5_fUllstsrslab分配圖解命令查看上面說(shuō)的都是理論,比較抽象,動(dòng)動(dòng)手來(lái)看看系統(tǒng)中的slab吧!你可以通過(guò)cat/proc/slabinfo命令,實(shí)際查看系統(tǒng)中slab信息。-Hfeg足|

24、1;nJMMcACERv*T*flU'曲air>cfi_tfrrrerfuai«o""afEdnnrni:k_*3mcawrikr"lutUlTl"m£crraridhiaUf*srid_a«.嗚倫百M(fèi)iL呻q血血畔Httjg叮WlxLB4I9KfHUhHfiwnan9eaap«4bpnl如1j>feAablis再r:TuMJjliKI-TU曲帕I;thiHtlffiI:thNbEfs4:touiblflfil:tdMblin1 :laMbSrsI.«toublK.2 sTJUtlKE

25、-tLJUbK1 ifUMbllK?JtJUbkH2 dtMt-lnL®申n作:sLabdaiaai;tLvHaiaar十1卄擊懾B:tsLiFNJiaaivii-MTA&:iLrHdiaai;LiWJi印L4IJrtKlJlJl印e<-LMauai!山諂m?k9.4山心恰PliLjMJtaT4*Lb韓C;ftljMfeClBa-:iiA£<1£-0Q*cisioocl目目sisicnraslabinfo查詢slabtop實(shí)時(shí)顯示內(nèi)核slab內(nèi)存緩存信息。Active/TotalObjects(驚used)Active-JTotalSlabs厲

26、used)Active/TotalCaches(%ue(1)Active/TotalSize(奄jsd)HinimumFAveragefMaxiuiumObject:3794240/39103&6(99.):L03652/103652(100.0):123/211(58.3%):536147.47K/644963.3QK(98.6);Q.01K/0.17Kf8.0QK0BJSACTIVEUSEOBJSIZE5LAB50BM5LABCACHE51在NfiWE5307102530079990.10K:643901925956QKbufferh出d5919403823499A6-20K195

27、972073388ICdentry.99512194D239A0.04K19561027824K.ext4_extentstatus935281LflGB1S98&3_3_abffl.B-39瞄1ccm0.93K_£1CL1*5692-abjir34GL1S2144KeKt4_inode_GacherertndrUInJslabtop查詢slab高速緩存的分類slab高速緩存分為兩大類,通用高速緩存和專用高速緩存。通用高速緩存slab分配器中用kmem_cache來(lái)描述高速緩存的結(jié)構(gòu),它本身也需要slab分配器對(duì)其進(jìn)行高速緩存。eache_cache保存著對(duì)高速緩存描述符的高

28、速緩存,是一種通用高速緩存,保存在eache_chain鏈表中的第一個(gè)元素。另外,slab分配器所提供的小塊連續(xù)內(nèi)存的分配,也是通用高速緩存實(shí)現(xiàn)的。通用高速緩存所提供的對(duì)象具有幾何分布的大小,范圍為32至到131072字節(jié)。內(nèi)核中提供了kmalloc()和kfree()兩個(gè)接口分別進(jìn)行內(nèi)存的申請(qǐng)和釋放。專用高速緩存內(nèi)核為專用高速緩存的申請(qǐng)和釋放提供了一套完整的接口,根據(jù)所傳入的參數(shù)為指定的對(duì)象分配slab緩存。專用高速緩存的申請(qǐng)和釋放kmem_cache_create()用于對(duì)一個(gè)指定的對(duì)象創(chuàng)建高速緩存。它從cache_cache普通高速緩存中為新的專有緩存分配一個(gè)高速緩存描述符,并把這個(gè)描述

29、符插入到高速緩存描述符形成的eache_chain鏈表中。kmem_cache_destory()用于撤消和從cache_chain鏈表上刪除高速緩存。slab的申請(qǐng)和釋放slab數(shù)據(jù)結(jié)構(gòu)在內(nèi)核中的定義,如下:stru'.tslabstiuc:ListheadItst;用i-s1abilAkeme_Ltst3*/unsignedlonqcolfluroff;嚴(yán)謨航曲的弄亀偏移voidilab'Pii'j.qj卜時(shí)®unsignedintinuse;ofobjsactiveinslab(2噲卄配出出的Wfe*/kmeni_bjfcfl_tfree;/土下-十亍1

30、卅對(duì)隹的F樁*funinedshortnodeid;rj|hJ|沖匚i慝I(xiàn),WluTl,T«J/;slab結(jié)構(gòu)體內(nèi)核代碼kmem_cache_alloc()在其參數(shù)所指定的高速緩存中分配一個(gè)slab,對(duì)應(yīng)的kmem_cache_free()在其參數(shù)所指定的高速緩存中釋放一個(gè)slab。虛擬內(nèi)存分配前面討論的都是對(duì)物理內(nèi)存的管理,Linux通過(guò)虛擬內(nèi)存管理,欺騙了用戶程序假裝每個(gè)程序都有4G的虛擬內(nèi)存尋址空間(如果這里不懂我說(shuō)啥,建議回頭看下別再說(shuō)你不懂Linux內(nèi)存管理了,10張圖給你安排的明明白白!)。所以我們來(lái)研究下虛擬內(nèi)存的分配,這里包括用戶空間虛擬內(nèi)存和內(nèi)核空間虛擬內(nèi)存。注意,

31、分配的虛擬內(nèi)存還沒(méi)有映射到物理內(nèi)存,只有當(dāng)訪問(wèn)申請(qǐng)的虛擬內(nèi)存時(shí),才會(huì)發(fā)生缺頁(yè)異常,再通過(guò)上面介紹的伙伴系統(tǒng)和slab分配器申請(qǐng)物理內(nèi)存。用戶空間內(nèi)存分配mallocmalloc用于申請(qǐng)用戶空間的虛擬內(nèi)存,當(dāng)申請(qǐng)小于128KB小內(nèi)存的時(shí),malloc使用sbrk或brk分配內(nèi)存;當(dāng)申請(qǐng)大于128KB的內(nèi)存時(shí),使用mmap函數(shù)申請(qǐng)內(nèi)存;存在問(wèn)題由于brk/sbrk/mmap屬于系統(tǒng)調(diào)用,如果每次申請(qǐng)內(nèi)存都要產(chǎn)生系統(tǒng)調(diào)用開銷,cpu在用戶態(tài)和內(nèi)核態(tài)之間頻繁切換,非常影響性能。而且,堆是從低地址往高地址增長(zhǎng),如果低地址的內(nèi)存沒(méi)有被釋放,高地址的內(nèi)存就不能被回收,容易產(chǎn)生內(nèi)存碎片。解決因此,malloc米用的是內(nèi)存池的實(shí)現(xiàn)方式,先申請(qǐng)一大塊內(nèi)存,然后將內(nèi)存分成不同大小的內(nèi)存塊,然后用戶申請(qǐng)內(nèi)存時(shí),直接從內(nèi)存池中選擇一塊相近的內(nèi)存塊分配出去。內(nèi)核空間細(xì)分區(qū)域kmallockmalloc()分配的虛擬地址范圍在內(nèi)核空間的直接內(nèi)存映射區(qū)。按字節(jié)為單位虛擬內(nèi)存,一般用于分配小塊內(nèi)存,釋放內(nèi)存對(duì)應(yīng)于kfree,可以分配連續(xù)的物理內(nèi)存。函數(shù)原型在<linux/kmalloc.h>中聲明,一般情況下在

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論