記憶體管理八 記憶體分配介面總結
一、簡介:
記憶體分配的介面有很多,不同的申請函式有不同的功能,下面會做詳細的介紹和對比。
- kmalloc:基於slab分配器,用於分配小記憶體,物理空間連續的記憶體塊;
- vmalloc:用於分配大記憶體,虛擬地址連續的記憶體;
- malloc:為使用者空間分配程序地址空間(即分配一塊VMA);
- mmap:使用者空間分配記憶體、讀寫大檔案和載入靜態庫等;
可以用下圖清晰的表明:
二、詳細說明:
1、kmalloc(size_t size, gfp_t flags):
(1)kmalloc基於slub分配器,分配實體地址連續的小記憶體;
(2)gfp_mask常用標誌:
- 程序上下文,可以睡眠 GFP_KERNEL
- 程序上下文,不可以睡眠 GFP_ATOMIC
- 中斷處理程式 GFP_ATOMIC
- 軟中斷 GFP_ATOMIC
- Tasklet GFP_ATOMIC
- 用於DMA的記憶體,可以睡眠 GFP_DMA | GFP_KERNEL
- 用於DMA的記憶體,不可以睡眠 GFP_DMA | GFP_ATOMIC
(3)kfree(const void *ptr)
釋放由kmalloc()分配出來的記憶體塊;
2、vmalloc(unsigned long size):
(1)vmalloc 用於分配核心空間裡連續虛擬地址的大記憶體塊,分配的大小要以頁面大小對齊(4Kb);
(2)vmalloc的函式如下:
void *vmalloc(unsigned long size) { return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); } vmalloc -> __vmalloc ->__vmalloc_node static void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask, pgprot_t prot, int node, const void *caller) { return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END, gfp_mask, prot, 0, node, caller); }
以上GFP_KERNEL | __GFP_HIGHMEM說明有效從High memory區域開始分配,分配的區域在
VMALLOC_START -VMALLOC_END之間,關於vmalloc的區域看檢視記憶體管理五中檢視。
(3)void vfree(void *addr)
用於釋放vmalloc申請的記憶體,這個函式可以睡眠,因此不能從中斷上下文呼叫。
3、void *malloc(size_t size):
(1)malloc是使用者空間使用者分配記憶體的介面;
(2)malloc分配函式分配空間分如下兩種情況:
testA通過malloc申請100Byte的記憶體時,其實是為使用者空間分配程序地址空間(分配一塊VMA),
在使用到buf的空間時,CPU才會觸發缺頁中斷,在缺頁中斷中一頁一頁的分配實體記憶體;
testB在申請記憶體時,申請的虛擬記憶體都已經分配了實體記憶體並建立了頁表對映;
void testA(void)
{
char *bufA = malloc(100);
* bufA = 100;
}
void testB(void)
{
char *bufB = malloc(100);
mlock(buf, 100);
}
(3)malloc對於使用者空間的使用非常簡單,但在核心空間會經過很多的處理,下面引用一張圖可以清晰的表明:
4、void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset):
(1)mmap/munmap是使用者空間常用的系統呼叫介面,用於使用者程式分配記憶體、讀寫大檔案、連結
動態庫檔案等;
(2)prot引數表示對映頁面的讀寫許可權:
- PROT_EXEC //頁內容可以被執行
- PROT_READ //頁內容可以被讀取
- PROT_WRITE //頁可以被寫入
- PROT_NONE //頁不可訪問
(3)flags引數:指定對映物件的型別,對映選項和對映頁是否可以共享。
作者:frank_zyp
您的支援是對博主最大的鼓勵,感謝您的認真閱讀。
本文無所謂版權,歡迎轉載。