一、内核内存分配
1、与应用程序中的malloc函数相对,在Linux内核中,通常使用kmalloc来动态分配内存
(1)原型: void * kmalloc(size_t size,int flags);
(2)参数:
i、size:要分配的内存大小
ii、flags:分配标志,它控制kmalloc的行为。flags的取值可以是:
a、GFP_ATOMIC,用来在进程上下文之外的代码(包括中断处理)中分配内存,从不睡眠。(16M-896M)
b、GFP_KERNEL,在进程上下文中分配内存。可能睡眠(16M-896M)
c、__GFP_DMA,这个标志要求分配能够DMA传输的内存区。(物理地址在16M以下的页帧)
d、__GFP_HIGHMEM,这个标志表示分配的内存位于高端内存。(869M以上)
(1)get_zeroed_page(unsigned int flags);返回指向新页面的指针,并将页面清零
(2)__get_free_page(unsigned int flags);和get_free_page类似,但不清零页面
(3)__get_free_pages(unsigned int flags,unsigned int order);分配若干个连续的页面,返回指向该内存区域的指针,但也不清零这段内存区域
3、释放,
I、当程序用完这些页,可以使用下列函数之一来释放他们
(1)void free_page(unsigned long addr)
(2)void free_pages(unsigned long addr,unsigned long order)
II、如果使用的是kmalloc分配的内存,则使用kfree来释放
4、
系统内存的使用方式可以分为3种形式(流程图分别用蓝、红、黑表示)
(1)来自用户空间app的内存分配请求(蓝色流程图),注意,此时系统只是给这个请求返回一段虚拟地址区间,并没有实际为它分配物理内存空间。只有当应用程序要访问这段内存空间时,才会产生一个缺页异常,然后通过get_free_page(s) 函数去系统的空闲页框中实实在在的获得一个内存单元
(2)来自内核的Kmalloc内存分配请求(红色流程图);这种请求机制中,有一个很重要的slab管理器。它的作用是:首先从系统空闲页框中分出一部分物理页框。然后再将这部分的物理页框分成若干个小的(会有不同的尺寸大小)存储单元并用链表链接起来。这样,kmalloc发出内存分配请求时,直接向slab去索取内存空间
(3)