Linux 申请内存

在用户空间动态申请内存

在用户空间中动态申请内存的函数为 malloc(),这个函数在各种操作上的使用都是一致的。与之对应的释放函数为 free()。

对于 Linux 而言,C 库的 malloc() 函数一般通过 brk() 和 mmap() 两个系统调用从内核申请内存。


在内核空间动态申请内存

在 Linux 内核空间中申请内存涉及的函数主要包括 kmalloc()、__get_free_pages() 和 vmalloc() 等。这里只介绍这3种。

1. kmalloc()

函数原型为:

void * kmalloc(size_t size, int flags);

size:要分配的块的大小

flags:分配标志,用于控制 kmalloc() 的行为,最常用是 GFP_KERNEL 和 GFP_ATOMIC

分配标志为 GFP_KERNEL 时,表示在内核空间的进程中申请内存。

使用 GFP_KERNEL 标志申请内存时,若暂时不能满足,则进程会睡眠等待也,即会引起阻塞,因此不能中断上下文或持有自旋锁的时候使用 GFP_KERNEL 申请内存。

由于在中断处理函数、tasklet 和内核定时器等非进程上下文中不能阻塞,所以此时驱动应当使用 GFP_ATOMIC 标志来申请内存。当使用 GFP_ATOMIC 标志申请内存时,若不存在空页,则不等待,直接返回。

2. __get_free_pages()

__get_free_pages() 系列函数/宏本质上是 Linux 内核最底层用于获取空闲内存的方法,因为底层的 buddy 算法以 2N 页为单位管理空闲内存,所以最底层的内存申请总是以 2N 页为单位的。

__get_free_pages() 系列函数/宏包括 get_zeroed_page()、__get_free_page() 和 __get_free_pages()。

kmalloc() 的底层依赖于 __get_free_pages() 来实现的。

3. vmalloc()

vmalloc() 一般只为存在于软件中(没有对应的硬件意义)的较大的顺序缓冲区分配内存,vmalloc() 远大于 __get_free_pages() 的开销,为了完成 vmalloc(),新的页表项需要被建立,因此,只是调用 vmalloc() 来分配少量的内存时不妥的。

vmalloc() 申请的内存使用 vfree() 释放。

vmalloc() 不能用在原子上下文中,因为它的内部实现了标志位 GFP_KERNEL 的 kmalloc()。

vmalloc() 在申请内存时,会进行内存的映射,改变页表项,不像 kmalloc() 实际用的是开机过程中就映射好的 DMA 和常规区域的页表项。因此 vmalloc() 的虚拟地址和物理地址不是一个简单的线性映射。

4. 总结

kmalloc() 和 __get_free_pages() 申请的内存在物理上连续,而 vmalloc() 申请的内存在物理上不连续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值