Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别
kzalloc与kmalloc区别  
 这个函数就是原来的两个函数的整合 , 即原来我们每次申请内存的时候都会这么做 , 先是用 kmalloc() 申请空间 , 然后用 memset()来初始化 , 而现在省事了 , 一步到位 , 直接调用 kzalloc(), 效果等同于原来那两个函数 , 所有申请的元素都被初始化为 0. 其实对写驱动的来说 , 知道现在应该用 kzalloc() 代替原来的 kmalloc() 和memset() 就可以了 , 这是内核中内存管理部分做出的改变 , 确切的说是改进 , 负责内存管理那部分的兄弟们的目标无非就是让内核跑起来更快一些 , 而从 kmalloc/memset 到 kzalloc 的改变确实也是为了实现这方面的优化
内核中的定义:
  1. static inline void *kzalloc(size_t size, gfp_t flags)
  2. {
  3. return kmalloc(size, flags | __GFP_ZERO);
  4. }

我们都知道在用户空间动态申请内存用的函数是 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 
 |  |– Tasklet         GFP_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() 的共同特点是:

  1. 用于申请内核空间的内存;
  2. 内存以字节为单位进行分配;
  3. 所分配的内存虚拟地址上连续;

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

  1. kzalloc 是强制清零的 kmalloc 操作;(以下描述不区分 kmalloc 和 kzalloc)
  2. kmalloc 分配的内存大小有限制(128KB),而 vmalloc 没有限制;
  3. kmalloc 可以保证分配的内存物理地址是连续的,但是 vmalloc 不能保证;
  4. kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞;
  5. kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快;

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

Linux 基础知识(2)---Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别相关推荐

  1. Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别

    Table of Contents kmalloc() kzalloc() vmalloc() 总结 内核中的内存申请:kmalloc.vmalloc.kzalloc.kcalloc.get_free ...

  2. Linux基础知识--2.Linux的文件系统和bash的基础特性(1)

    Linux基础知识--linux的文件系统和bash的基础特性 一.Linux文件系统: Linux文件系统中的文件是数据的集合,文件系统不仅包含着文件中的数据而且还有文件系统的结构,所有Linux ...

  3. linux 内核 内存申请函数 kmalloc、kzalloc、vmalloc 区别

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

  4. 【Linux】Linux基础知识(Linux模块)

    Linux的内核模块机制允许开发者动态的向内核添加功能,我们常见的文件系统.驱动程序等都可以通过模块的方式添加到内核而无需对内核重新编译,这在很大程度上减少了操作的复杂度.模块机制使内核预编译时不必包 ...

  5. linux dd入门,Linux基础知识:Linux中DD命令详解

    1.dd命令简介 功能:把指定的输入文件拷贝到指定的输出文件中,并且在拷贝过程中可以进行格式转换.可以用该命令实现DOS下的diskcopy命令的作用.先用dd命令把软盘上的数据写成硬盘的一个寄存文件 ...

  6. linux.命令格式,【Linux基础知识】Linux命令格式介绍

    Linux系统中每一命令都提供特定的系统功能,尽管命令繁多,但是在命令的使用形式上存在一定的共性,概况起来,Linux命令具有下面的通用格式: 命令字 [选项] [参数] ("[ ]&quo ...

  7. linux yum ku,Linux基础知识:Linux yum 配置与使用

    本篇只讨论RHEL 5系列的YUM源(仓库)配置. 关于linux下面yum仓库的配置, Yum介绍 Yum全称为 Yellow dog Updater, Modified(软件包管理器) 主要功能是 ...

  8. Linux基础知识梳理

    Linux基础知识梳理 Linux系统的学习的方法: 1. 做一个属于自己的笔记. 2. 学习方法:实验多敲几遍, 服务器硬件 一般的服务器 刀片服务器 Linux操作系统最初是在1991年10月份由 ...

  9. linux内核空间内存动态申请

    参考:<linux设备驱动开发详解>华清远见 ,--人民邮电出版社 用户空间内存动态申请 在用户空间动态申请内存的函数为 malloc(),这个函数在各种操作系统上的使用是一致的,mall ...

最新文章

  1. 与后台交互方法一 ——Ajax
  2. mysql左连接丢失null值的问题
  3. DL框架之TensorFlow:深度学习框架TensorFlow Core(低级别TensorFlow API)的简介、安装、使用方法之详细攻略
  4. java linux 调用32位so_Linux上TCP的几个内核参数调优
  5. pytorch 指定卡1_收藏 | 13则PyTorch使用的小窍门
  6. (IoT物联网)天线的设计步骤 - 完整收藏版
  7. 经典:5种常见的数据分析方法
  8. LordPe dump进程内存实现
  9. Slurm的前处理prolog和后处理epilog
  10. 计算机定时关机教程,Win7系统电脑设置定时关机和取消定时关机的教程
  11. 将SQL导入JAVA的后续操作
  12. 食物语电脑版服务器一直维护,《食物语》进不去解决办法(图文)
  13. 数据结构:数组和链表的区别以及各自的优缺点
  14. kvaser leaf light v2 安装 UBUNTU
  15. 无法在已有的 xxxxxxx“上还原文件 zzz。请重新发出 RESTORE 语句,用 WITH REPLACE 来覆盖原先存在的文件
  16. 豆瓣电台WP7客户端 开发记录4
  17. python web微信应用(二) webwx 模块源码
  18. Unity利用单反相机拍照、录制视频
  19. 树莓派驱动OLED显示屏
  20. pixi.js 总结

热门文章

  1. linux多线程学习(五)——信号量线程控制
  2. 详细剖析linux的内存管理方式(分段式、分页式、段页式),以及进程状态的具体关系
  3. 嵌入式Linux系统编程学习之六make工程管理和Makefile
  4. HTML在日期单元格添加小图片,如何给图片添加上文字、日期和自己名字的小水印呢?...
  5. mysql如何给数据增加tab_怎么往mysql表里添加数据
  6. Cyclone IV FPGA 器件笔记
  7. PHP设计模式练习——制作简单的投诉页面
  8. eclipse中的JSP项目连接mysql报错,找不到jdbc驱动,java项目却没问题
  9. 6.5 Introduce Explaining Variable(引入解释性变量)
  10. 用jsp开发web应用并不是一个高效率的选择