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