[Linux源码分析]内存管理
一、 內(nèi)核空間
1. 頁(yè)page(是內(nèi)核空間管理基本單位)源代碼分析如下:/include/linux/mm_types.h
內(nèi)存管理單元(MMU,把虛擬地址轉(zhuǎn)換為物理地址的硬件設(shè)備)通常是以頁(yè)為單位處理。
內(nèi)核用struct page結(jié)構(gòu)體表示每個(gè)物理頁(yè),struct page占用40個(gè)字節(jié)。
2. 區(qū)(zone,內(nèi)核把頁(yè)劃分在不同的區(qū))
共記3個(gè)區(qū):
ZONE_DMA(DMA使用的頁(yè),物理內(nèi)存<16MB)
ZONE_NORMAL(可以正常尋址的頁(yè),物理內(nèi)存16—896MB)
ZONE_HIGHMEM(動(dòng)態(tài)映射的頁(yè),物理內(nèi)存>896MB)
執(zhí)行DMA操作必須從ZOME_DMA區(qū)分配,一般內(nèi)存,既可以從ZOME_DMA,也可以從ZONE_NORMAL分配,但不能從兩個(gè)區(qū)分配。
3. 頁(yè)的分配與釋放
所有頁(yè)為單位進(jìn)行連續(xù)的物理內(nèi)存分配,也稱(chēng)為低級(jí)頁(yè)分配,alloc_page、alloc_pages、
__get_free_pages、__get_free_pages、__get_zeroed_page.
釋放函數(shù):__free_pages、free_pages、free_page.
4. 字節(jié)分配與釋放(kmalloc/vmalloc,分配都是以字節(jié)為單位)
Void *kmalloc(size_t size,gpf_t flags);
Kmalloc 函數(shù)返回指向內(nèi)存塊的指針,內(nèi)存塊大小至少size,所分配內(nèi)存在物理內(nèi)存中連續(xù)且保持原有的數(shù)據(jù)(不清零)。
Flags取值說(shuō)明(常用部分如下):
GFP_USER-用于用戶(hù)空間分配內(nèi)存,可能休眠
GFP_KERNEL-用于內(nèi)核空間分配內(nèi)存,可能休眠
GFP_ATOMATIC-用于原子性的分配內(nèi)存,不會(huì)休眠,典型原子性場(chǎng)景,中斷處理程序、軟中斷。
Kamlloc函數(shù)用于內(nèi)存分配最終會(huì)調(diào)用_get_free_pages進(jìn)行實(shí)際分配,前綴都是GFP_開(kāi)頭。 Kamalloc分配最多只能分配32個(gè)page大小的內(nèi)存,每一個(gè)page=4k,也就是分配128k大小,其中16個(gè)字節(jié)用來(lái)記錄頁(yè)的描述結(jié)構(gòu)。所分配的是常駐內(nèi)存,不會(huì)被交換到文件中,最小分配單位是32或64個(gè)字節(jié)。
Vmalloc函數(shù):返回是一個(gè)指向內(nèi)存塊的指針,內(nèi)存塊大小至少是size,它所分配的內(nèi)存是邏輯上了連續(xù)的,該函數(shù)也有flags,默認(rèn)它是可以休眠的。 Kmalloc:所在區(qū)域內(nèi)核空間,物理地址連續(xù),最大值為128k-16k,釋放函數(shù)free,性能最佳 Vmalloc: 所在區(qū)域內(nèi)核空間,虛擬地址連續(xù),更大,釋放函數(shù)vfree,更容易分配大內(nèi)存。 Malloc: 所在區(qū)域用戶(hù)空間,虛擬地址連續(xù),更大,釋放函數(shù)free。二、 slab分配器的功能
對(duì)于頻繁地分配和釋放的數(shù)據(jù)結(jié)構(gòu),會(huì)緩存它;
頻繁分配和回收,比如導(dǎo)致內(nèi)存碎片、為了避免,空間鏈表的緩存會(huì)連續(xù)的存放,已釋放的數(shù)據(jù)結(jié)構(gòu)又會(huì)放回空閑鏈表,不會(huì)導(dǎo)致碎片。
記部分緩存專(zhuān)屬單個(gè)處理器,分配和釋放操作可以不加SMP鎖。
三、 slab分配器層的設(shè)計(jì)
slab層把不同的對(duì)象劃分所謂的高速緩存組,其中每個(gè)緩存組都存放不類(lèi)型的對(duì)象。每一種對(duì)象類(lèi)型對(duì)應(yīng)一個(gè)高速緩存。比如:一個(gè)高速緩存用于進(jìn)程描述符(task_struct結(jié)構(gòu)的一個(gè)空閑鏈表),另外一個(gè)高速緩存存放索引節(jié)點(diǎn)對(duì)象(struct inode).
Kmalloc()接口建立在slab層上的,使用一組通用高速緩存。
這些高速緩存又被劃分為slab,slab由一個(gè)或多個(gè)物理上連續(xù)的頁(yè)page組成,一般情況下,slab也就僅僅由頁(yè)組成。每個(gè)高速緩存可以由多個(gè)slab組成。
四、 slab的接口分配器(參考源代碼fork.c)
每當(dāng)進(jìn)程調(diào)用fork時(shí),一定會(huì)創(chuàng)建一個(gè)新的進(jìn)程描符,這是在dup_task_struct()進(jìn)程中完成,而該函數(shù)會(huì)被do_fork()調(diào)用.執(zhí)行完畢后,如果沒(méi)有子進(jìn)程在等待的話,它的進(jìn)程描述符就會(huì)被釋放。返回給task_struct_cachep slab高速緩存。
Slab層負(fù)責(zé)在內(nèi)存緊缺情況下所有底層的對(duì)齊、著色、分配、釋放、回收等。如果我們要頻繁創(chuàng)建很多相同類(lèi)型的對(duì)象,就因該考慮使用slab高速緩存。
總結(jié)
以上是生活随笔為你收集整理的[Linux源码分析]内存管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2022年6月深圳地区数据分析师认证(C
- 下一篇: 漫画-Linux中断子系统综述