0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

申请函数kmalloc、kzalloc、vmalloc区别说明

Linux内核补给站 来源:Linux内核补给站 作者:Linux内核补给站 2022-05-19 16:13 次阅读

我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一致的,对应的用户空间内存释放函数是 free()。注意:动态申请的内存使用完后必须要释放,否则会造成内存泄漏,如果内存泄漏发生在内核空间,则会造成系统崩溃。

那么,在内核空间中如何申请内存呢?一般我们会用到 kmalloc()、kzalloc()、vmalloc() 等,下面我们介绍一下这些函数的使用以及它们之间的区别。

kmalloc()

函数原型:

void *kmalloc(size_t size, gfp_t flags);

kmalloc() 申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因为存在较简单的转换关系,所以对申请的内存大小有限制,不能超过128KB。

较常用的 flags(分配内存的方法):

GFP_ATOMIC —— 分配内存的过程是一个原子过程,分配内存的过程不会被(高优先级进程或中断)打断;

GFP_KERNEL —— 正常分配内存;

GFP_DMA —— 给 DMA 控制器分配内存,需要使用该标志(DMA要求分配虚拟地址和物理地址连续)。

flags 的参考用法:

|– 进程上下文,可以睡眠GFP_KERNEL |– 进程上下文,不可以睡眠GFP_ATOMIC ||– 中断处理程序GFP_ATOMIC ||– 软中断GFP_ATOMIC ||– TaskletGFP_ATOMIC |– 用于DMA的内存,可以睡眠GFP_DMA | GFP_KERNEL |– 用于DMA的内存,不可以睡眠GFP_DMA |GFP_ATOMIC

对应的内存释放函数为:

void kfree(const void *objp);

kzalloc()

kzalloc() 函数与 kmalloc() 非常相似,参数及返回值是一样的,可以说是前者是后者的一个变种,因为 kzalloc() 实际上只是额外附加了__GFP_ZERO标志。所以它除了申请内核内存外,还会对申请到的内存内容清零。

/** * kzalloc - allocate memory. The memory is set to zero. * @size: how many bytes of memory are required. * @flags: the type of memory to allocate (see kmalloc). */static inline void *kzalloc(size_t size, gfp_t flags){    return kmalloc(size, flags | __GFP_ZERO);}

kzalloc() 对应的内存释放函数也是 kfree()。

vmalloc()

函数原型:

void *vmalloc(unsigned long size);

vmalloc() 函数则会在虚拟内存空间给出一块连续的内存区,但这片连续的虚拟内存在物理内存中并不一定连续。由于 vmalloc() 没有保证申请到的是连续的物理内存,因此对申请的内存大小没有限制,如果需要申请较大的内存空间就需要用此函数了。

对应的内存释放函数为:

void vfree(const void *addr);

注意:vmalloc() 和 vfree() 可以睡眠,因此不能从中断上下文调用。

总结

kmalloc()、kzalloc()、vmalloc() 的共同特点是:

用于申请内核空间的内存;

内存以字节为单位进行分配;

所分配的内存虚拟地址上连续;

kmalloc()、kzalloc()、vmalloc() 的区别是:

kzalloc 是强制清零的 kmalloc 操作;(以下描述不区分 kmalloc 和 kzalloc)

kmalloc 分配的内存大小有限制(128KB),而 vmalloc 没有限制;

kmalloc 可以保证分配的内存物理地址是连续的,但是 vmalloc 不能保证;

kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞;

kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快;

一般情况下,内存只有在要被 DMA 访问的时候才需要物理上连续,但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用 vmalloc()。例如,当模块被动态加载到内核当中时,就把模块装载到由 vmalloc() 分配的内存上。

审核编辑:符乾江

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    2737

    浏览量

    72613
  • 函数
    +关注

    关注

    3

    文章

    3845

    浏览量

    61214
  • malloc
    +关注

    关注

    0

    文章

    52

    浏览量

    37
收藏 人收藏

    评论

    相关推荐

    路由器CCC认证申请流程,发证周期多长?

    CCC认证的申请流程以及该类型产品的发证周期。以下是CCC认证申请流程的大致步骤:1.申请准备:准备好申请材料,包括申请表、产品
    的头像 发表于 01-11 16:33 177次阅读
    路由器CCC认证<b class='flag-5'>申请</b>流程,发证周期多长?

    移植ADV7180驱动时,在执行探测函数adv7180_probe的kzalloc分配内存时返回NULL,可确实还有内存是怎么回事?

    移植ADV7180驱动时,在执行探测函数adv7180_probe的kzalloc分配内存时返回NULL,可确实还有内存,这是怎么回事?
    发表于 12-12 07:00

    嵌入式C编码中函数的规范

    ◎ 一个函数仅完成一件功能 ◎ 重复代码应该尽可能提炼成函数说明:重复代码提炼成函数可以带来维护成本的降低。重复代码是不良代码最典型的特征之一。在“代码能用就不改”的指导原则之下,
    的头像 发表于 12-07 14:33 158次阅读

    append()和insert()函数区别

    在Python中, append() 和 insert() 是用于修改列表的两个常用函数。这两个函数的主要区别在于元素添加的位置和方式。 首先,让我们来了解一下 append() 函数
    的头像 发表于 11-21 14:44 914次阅读

    malloc 申请内存的两种方式

    我们知道malloc() 并不是系统调用,也不是运算符,而是 C 库里的函数,用于动态分配内存。 malloc 申请内存的时候,会有两种方式向操作系统申请堆内存: 方式一:通过 brk() 系统调用
    的头像 发表于 11-13 11:42 882次阅读
    malloc <b class='flag-5'>申请</b>内存的两种方式

    零点和极点的作用 复变函数的极点和零点有什么区别和联系?

    零点和极点的作用 复变函数的极点和零点有什么区别和联系? 复变函数是指自变量和函数值都是复数的函数。在复平面上,复变
    的头像 发表于 11-08 17:46 2978次阅读

    如何绑架C语言标准库函数

    C语言动态内存可以使用 malloc 标准库函数,而 C++ 会使用 new 关键字申请,裸机情况下一般没有问题,但是在 RTOS 情况下,就需要考虑资源保护的情况,比如多个任务同时
    发表于 11-01 09:50 234次阅读

    函数类型和函数指针类型的区别

    平时用的更多的是函数指针类型,比如作为函数参数传入回调函数等等。实际上函数类型也是可以作为函数的参数进行传递的。
    发表于 10-24 14:27 128次阅读

    通过函数指针调用函数,需不需要加星号?

    先来说下结论,不管是获取函数地址,还是通过函数指针调用函数,两种写法都可以,就用法上来说,没有什么区别,初学者也不必过多纠结。
    的头像 发表于 09-05 17:05 611次阅读

    Matlab数据导入-importdata和load函数说明

    在使用matlab将数据导入到工作空间的时候,经常会使用到两个函数,一个是importdata函数,另一个是load函数,它们的使用方法和使用场景是太相同的,如果不太注意就可能会犯错误,在这里做简要的
    的头像 发表于 07-19 16:00 1280次阅读
    Matlab数据导入-importdata和load<b class='flag-5'>函数说明</b>

    VB API函数大全

    VB程式开发所使的最全AIP函数使用说明.
    发表于 07-10 16:31 0次下载

    Linux Regmap 操作函数

    Regmap 操作函数 1、Regmap 申请与初始化 regmap 支持多种物理总线,比如 I2C 和 SPI,我们需要根据所使用的接口来选择合适的 regmap 初始化函数。Linux 内核提供
    的头像 发表于 07-06 17:31 1587次阅读

    Verilog任务与函数区别

    函数一样,任务(task)可以用来描述共同的代码段,并在模块内任意位置被调用,让代码更加的直观易读。
    的头像 发表于 06-01 16:38 929次阅读
    Verilog任务与<b class='flag-5'>函数</b>的<b class='flag-5'>区别</b>

    函数信号发生器和示波器有什么区别呢?

    函数信号发生器和示波器有什么区别呢?
    发表于 04-19 18:20

    函数结构的定义和例程说明

    在理解拷贝构造函数前,还是有必要回顾下类的构造函数基本概念。类的构造函数是一种特殊的成员函数,它在创建类的对象时执行。构造函数
    的头像 发表于 04-19 11:35 590次阅读