函数有
kmalloc
get_free_page()
__get_free_pages()
__get_free_page()
vmalloc
kmem_cache
kmem_cache_alloc
linux内存分为3中,DMA(可以直接访问),normal memory,high memory
一般内存中,前16M是DMA内存,一般提供给ISA设备。high memory用在32位系统访问大地址空间,不能直接用,要映射。
kmalloc
#include<linux/slab.h>
char *ptr=(char*)kmalloc(1024,GFP_KERNEL)
memset(ptr,0,1024);
kfree(ptr);
GFP_KERNEL,内核正常分配内存,空闲内存少时候,进入休眠等待页面,当进程休眠,内核采取适当动作获取空闲页,所以用他来分配,必须可重入,不能在原子上下文运行。
GFP_ATOMIC,中断上下文使用,不会导致函数睡眠。
另外还有附加GFP_USTER(可能睡眠),GFP_HIGHUSER(如果有高端内存,从高端内存分配),__GFP_DMA,__GFP_HIGHMEM
使用小内存时用kmalloc
vmalloc
#include <linux/vmalloc.h>
vmalloc
vfree
__get_free_pages()
按4k页分配内存
ptr=(char*)__get_free_pages(GFP_KERNEL,3)//3是2的3次方个内存页
memset(ptr,0,PAGE_SIZE<<3);
free_pages((unsigned long)ptr,3);
kmem_cache_alloc
频繁分配固定大小内存页
typedef struct_MALLOC_FREE
{
int a;
int b;
}MALLOC_FREE,*PMALLOC_FREE;
struct kmem_cache my_cache;
MALLOC_FREE *mptr;
my_cache=Kmem_cache_create("mycache",sizeof(MALLOC_FREE));
mptr=kmem_cache_alloc(my_cache,GFP_KERNEL);
kmem_cache_free(cache,mptr);
if(cache)
kmem_cache_destroy(my_cache);
区别与选择
kmalloc()和__get_free_pages()申请的虚拟内存位于物理内存映射区域(<=896M),在物理上连续,与真实物理地址只有一个固定偏移,所以存在简单转换关系。
kmalloc只能分配小块内存,快,不会手动清零,没有空闲可能会发生swap
vmalloc不一定连续,虚拟内存物理内存没有简单换算关系。无法再原子上下文使用。
kmem_cache分配同样大小的内存页
__get_free_pages:分配大块页内存。