12、内存空间的申请

1、用户空间内存的申请

    用户空间内存的申请函数为 malloc,相对应的内存释放函数为 free。malloc 函数具备一下的内存能力

(1)二次管理的的能力

    当用户空间 malloc 了一块内存,这块被申请的内存被立即 free 之后,并不会立即将这块内存还给内核,而是将这块内存还给了 C 库,这块内存还是属于这个进程,只是将这块内存交给 C 库去进行管理。因此后续的内存申请,就可以占用这块被释放的内存了。

(2)Linux 内核总是按需分配

    当 malloc 成功之后,返回。虽然是成功返回,但是内核并没有将这块内存真正给进程,这个时候,如果去读的话,会发现内容全部是零,而且这个内存也是只读的。当在写这个内存的时候,内核会在出现页错误的时候,真正把这块内存给这个进程。

2、内核空间动态申请内存

2.1、kmalloc

   void * kmalloc(size, flags)

    size ,分配内存大小。flags,分配的标志,一般较为常用的是 GFP_KERNEL,GFP_AROMIC。

    kmalloc 申请的内存,位于 DMA映射区,最重要的是,物理上,也是连续的,它们与真是的物理地址只有一个固定的便宜。这一点对 DMA 至关重要。

    kmalloc 分配内存空间的大小,一般是比较的小,大小为 128KB-16B。

    当 flags 是 GFP_KERNEL 的时候,若是申请内存空间的请求不被满足,则进程就会睡眠,引起阻塞。所以,标志为 GFP_KERNEL 的话,就不能出现在中断的上下文,自旋锁,或者原子操作中。所以,在中断的上下文, ,tasklet、内核的定时器,等不能出现进程切换的位置中,就只能使用 GFP_ATOMIC 去申请内存,若是此时申请不到的话,就不等待睡眠了,直接进行返回。、 

    使用 kfree 去释放申请的内存空间。

2.2、vmalloc

    vmalloc 使用方法类似,但是 vmalloc 一般是用于申请内存空间较大的应用场景,而且,vmalloc 申请的内存空间,只在虚拟内存空间上是连续的,但是实质上,在物理内存空间并不一定连续。所以,申请的虚拟地址空间和实际的物理地址空间更没有固定的偏移关系。

    vmalloc 内部的实现,是借助了 GFP_KERNEL 标志的 kmalloc 去实现的,所以,vmalloc 也是不能用在原子的上下文。

   同理,使用 vfree 去进行内存的释放。

原文地址:https://www.cnblogs.com/qxj511/p/5509831.html