Linux学习-内存管理篇(五)-内存分配函数

一、kmalloc、vmalloc、malloc
  • malloc: 负责分配用户空间内存。malloc是标准的C库函数,在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由sark、brk、mmap、munmap这些系统调用实现的。

  • kmalloc:负责分配内核空间内存。用于申请较小的、连续的物理内存。以字节为单位进行分配,在中,内存由于是线性映射,所以使用kmalloc分配内存是十分高效的。内存只有在要被DMA访问的时候才需要物理上连续。

  • vmalloc:负责分配内核空间内存。用于申请较大的内存空间,虚拟内存是连续的,以字节为单位进行分配,在中,vmalloc并不是简单的线性映射,它获取的内存并不是连续的,其转换逻辑比较复杂,分配速度上,自然vmalloc比kmalloc要慢。

另外还有几点值得一提:

1)寄存器是通过ioremap向vmalloc映射区去映射的,一旦调用ioremap,Linux就从vmalloc映射区找一个空闲的虚拟地址空间,然后去修改进程的页表,把这个虚拟地址往这个寄存器的物理地址去指。所以vmalloc映射区,除了vmalloc函数分配的内存会映射在该区域,设备的寄存器也同样会通过ioremap映射到该区域。

2)malloc、vmalloc申请内存后需要修改页表,而kmalloc申请内存时由于已经做了开机线性映射,所以不需要修改页表。

3)一般情况下在驱动程序中都是调用kmalloc()来给数据结构分配内存,而vmalloc()用在为活动的交换区分配数据结构,为某些I/O驱动程序分配缓冲区,或为模块分配空间。

二、常用函数总结:

用户空间:

API名称 是否物理连续 大小限制 单位 场景
malloc/calloc/realloc/free 不保证 堆申请 字节 calloc初始化为0;realloc改变内存大小。
alloca 栈申请 字节 向栈申请内存
mmap/munmap 将文件利用虚拟内存技术映射到内存中去。
brk、sbrk 虚拟内存到内存的映射。sbrk(0)返回program break地址,sbrk调整对的大小。

内核空间:

API名称 是否物理连续 大小限制 单位 场景
vmalloc/vfree 虚拟连续 物理不定 vmalloc区大小限制 页VMALLOC区域 可能睡眠,不能从中断上下文中调用,或其他不允许阻塞情况下调用。VMALLOC区域vmalloc_start~vmalloc_end之间,vmalloc比kmalloc慢,适用于分配大内存。
  • 内核空间的slab:
API名称 是否物理连续 大小限制 单位 场景
kmalloc/kcalloc/krealloc/kfree 物理连续 64B-4MB (随slab而变) 2^order字 Normal区域 大小有限,不如vmalloc/malloc大。最大/小值由KMALLOC_MIN_SIZE/KMALLOC_SHIFT_MAX,对应64B/4MB。从/proc/slabinfo中的kmalloc-xxxx中分配,建立在kmem_cache_create基础之上。
kmem_cache_create 物理连续 64B-4MB 字节大小,需对齐 Normal区域 便于固定大小数据的频繁分配和释放,分配时从缓存池中获取地址,释放时也不一定真正释放内存。通过slab进行管理。
  • 内核空间的buddy:
API名称 是否物理连续 大小限制 单位 场景
__get_free_page/__get_free_pages 物理连续 4MB(1024页) 页 Normal区 __get_free_pages基于alloc_pages,但是限定不能使用HIGHMEM。
alloc_page/alloc_pages/free_pages 物理连续 4MB 页 Normal/Vmalloc都可 CONFIG_FORCE_MAX_ZONEORDER定义了最大页面数2^11,一次能分配到的最大页面数是1024。

参考:

http://www.cnblogs.com/wuchanming/p/4465155.html
http://www.cnblogs.com/arnoldlu/p/8251333.html

你可能感兴趣的:(Linux学习-内存管理篇(五)-内存分配函数)