11.3.1 用户空间内存动态申请
#include <malloc.h>
在用户空间中动态申请内存的函数为malloc(),这个函数在各种操作系统上的使用都是一致的,malloc()申请的内存的释放函数为free()。对于Linux而言,C库的malloc()函数一般通过brk()和 mmap()两个系统调用从内核申请内存。
备注:由于用户空间C库的malloc算法实际上具备一个二次管理能力,所以并不是每次申请和释放内存都一定伴随着对内核的系统调用。
Linux内核总是采用按需调页,当malloc()返回的时候,虽然成功返回,但内核并没有真正给这个进程内存,这时如果去读申请的内存,内容全部是0,这个页面的映射是只读的。只有当写到某个页面的时候,内核才在页错误后,真正把这个页面给这个进程。
11.3.2 内核空间内存动态申请
在Linux内核空间中申请内存涉及的函数:kmalloc()、kzalloc()、vmalloc()、__get_free_pages()等。
kmalloc()和__get_free_pages()(及其类似函数)申请的内存位于DMA和常规区域的映射区,在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,存在较简单的转换关系。
vmalloc()在虚拟内存空间给出一块连续的内存区,这片连续的虚拟内存在物理内存中并不一定连续,因此,vmalloc()申请的虚拟内存和物理内存之间没有简单的换算关系。
1.kmalloc()
#include <linux/slab.h>
void *kmalloc(size_t size, int flags);
第一个参数是要分配的块的大小;
第二个参数为分配标志,用于控制kmalloc()的行为。最常用的分配标志是GFP_KERNEL,其含义是在内核空间的进程中申请内存。
kmalloc()的底层依赖于__get_free_pages()来实现,分配标志的前缀GFP是这个底层函数的缩写。使用GFP_KERNEL标志申请内存时,若暂时不能满足,则进程会睡眠等待页,即会引起阻塞,不能在中断上下文或持有自旋锁时使用GFP_KERNE申请内存。
由于