一、分布位置上的區別:
kmalloc()和__get_free_pages()函數申請的內存位於物理內存的映射區域,而且在物理上也是連續的,它們與真實的物理地址只有一個固定的偏移,因此存在簡單的線性關系;(3G+896M)(低端內存);
vmalloc函數申請的虛擬內存與物理內存之間也沒有簡單的換算關系;(高端內存)(3G+896M以上的內存);
二、特性上的區別:
1、kmalloc()
void *kmalloc(size_t size, int flags);
kmalloc第一個參數是要分配塊的大小,第二個參數為分配標志,用於控制kmalloc的行為;
最常用的分配標志是GFP_KERNEL,其含義是內核空間的進程中申請內存。kmalloc()的底層依賴__get_free_page()實現,分配標志的前綴GFP正好是底層函數的縮寫。
kmalloc申請的是較小的連續的物理內存,內存物理地址上連續,虛擬地址上也是連續的,使用的是內存分配器slab的一小片。申請的內存位於物理內存的映射區域。其真正的物理地址只相差一個固定的偏移。可以用兩個宏來簡單轉換__pa(address) { virt_to_phys()} 和__va(address) {phys_to_virt()}
使用kmalloc函數之后使用kfree函數;
2、__get_free_pages()
get_free_page()申請的內存是一整頁,一頁的大小一般是128K。
從本質上講,kmalloc和get_free_page最終調用實現是相同的,只不過在調用最終函數時所傳的flag不同而已。
3、vmalloc()
vmalloc()一般用在只存在於軟件中的較大順序緩沖區分配內存,vmalloc()遠大於__get_free_pages()的開銷,為了完成vmalloc(),新的頁表需要被建立。所以效率沒有kmalloc和__get_free_page效率高;
三、另外的一些東西:
kmalloc()
用於申請較小的、連續的物理內存
1. 以字節為單位進行分配,在<linux/slab.h>中
2. void *kmalloc(size_t size, int flags) 分配的內存物理地址上連續,虛擬地址上自然連續
3. gfp_mask標志:什么時候使用哪種標志?如下:
———————————————————————————————-
情形 相應標志
———————————————————————————————-
進程上下文,可以睡眠 GFP_KERNEL
進程上下文,不可以睡眠 GFP_ATOMIC
中斷處理程序 GFP_ATOMIC
軟中斷 GFP_ATOMIC
Tasklet GFP_ATOMIC
用於DMA的內存,可以睡眠 GFP_DMA | GFP_KERNEL
用於DMA的內存,不可以睡眠 GFP_DMA | GFP_ATOMIC
———————————————————————————————-
kzalloc函數