LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

linux 用户空间内存申请 kmallockzallocmalloc和get_free_malloc_start这段地址

2022年12月2日 186点热度

kmalloc kzalloc vmalloc malloc 和get_free_page()的区别一、简述

1、kmalloc 申请的是较小的连续的物理内存,虚拟地址上也是连续的。kmalloc和get_free_page最终调用实现是相同的,只不过在调用最终函数时所传的flag不同而已。除非被阻塞否则他执行的速度非常快,而且不对获得空间清零。

2、get_free_page ()申请的内存是一整页,一页的大小一般是128K。

3、kzalloc 先是用kmalloc()申请空间,然后用memset()清零来初始化,所有申请的元素都被初始化为0.

4、vmalloc 用于申请较大的内存空间,虚拟内存是连续linux定时关机命令,但是在物理上它们不要求连续。

5、malloc 用于用户空间申请内存。除非被阻塞否则他执行的速度非常快,而且不对获得空间清零。

二、先看看linux内存分布图:

图1:linux内存分布图

对于提供了MMU(存储管理器linux 输入法,辅助操作系统进行内存管理,提供虚实地址转换等硬件支持)的处理器而言,Linux提供了复杂的存储管理系统,使得进程所能访问的内存达到4GB。

进程的4GB内存空间被人为的分为两个部分–用户空间与内核空间。用户空间地址分布从0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB为内核空间。

内核空间中,从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页框表mem_map等等),比如我们使用 的 VMware虚拟系统内存是160M,那么3G~3G+160M这片内存就应该映射物理内存。在物理内存映射区之后,就是vmalloc区域。对于 160M的系统而言,vmalloc_start位置应在3G+160M附近(在物理内存映射区与vmalloc_start期间还存在一个8M的gap 来防止跃界),vmalloc_end的位置接近4G(最后位置系统会保留一片128k大小的区域用于专用页面映射)

1、kmalloc

kmalloc申请的是较小的连续的物理内存,内存物理地址上连续,虚拟地址上也是连续的,使用的是内存分配器slab的一小片。申请的内存位于物理内存的映射区域。其真正的物理地址只相差一个固定的偏移。可以用两个宏来简单转换__pa(address) { virt_to_phys()} 和__va(address) {phys_to_virt()}

get_free_page()申请的内存是一整页,一页的大小一般是128K。

从本质上讲,kmalloc和get_free_page最终调用实现是相同的,只不过在调用最终函数时所传的flag不同而已。

kmalloc和get_free_page申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系,virt_to_phys()可以实现内核虚拟地址转化为物理地址:

define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)

extern inline unsigned long virt_to_phys(volatile void * address)

{

return __pa(address);

}

上面转换过程是将虚拟地址减去3G(PAGE_OFFSET=0XC000000)。

与之对应的函数为phys_to_virt(),将内核物理地址转化为虚拟地址:

define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))

extern inline void * phys_to_virt(unsigned long address)

c语言申请内存空间_linux 用户空间 mtd_linux 用户空间内存申请

{

return __va(address);

}

virt_to_phys()和phys_to_virt()都定义在include/asm-i386/io.h中。

kmalloc的用法

kmalloc与malloc 相似,该函数返回速度快快(除非它阻塞)并对其分配的内存不进行 初始化(清零),分配的区仍然持有它原来的内容, 分配的区也是在物理内存中连 续

记住 kmalloc 原型是:include2、kzalloc

用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0.

c语言申请内存空间_linux 用户空间内存申请_linux 用户空间 mtd

static inline void *kzalloc(size_t size, gfp_t flags){return kmalloc(size, flags | __GFP_ZERO);}

kzalloc 函数是带参数调用kmalloc函数,添加的参数是或了标志位__GFP_ZERO,

void *__kmalloc(size_t size, gfp_t flags){struct kmem_cache *s;void *ret;if (unlikely(size > SLUB_MAX_SIZE))return kmalloc_large(size, flags);s = get_slab(size, flags);if (unlikely(ZERO_OR_NULL_PTR(s)))return s;ret = slab_alloc(s, flags, -1, RET_IP);trace_kmalloc(RET_IP, ret, size, s->size, flags);return ret;}

这个函数调用trace_kmalloc,flags参数不变,继续往里面可以看到

static __always_inline void slab_alloc(struct kmem_cache s,gfp_t gfpflags, int node, unsigned long addr){void **object ;struct kmem_cache_cpu *c;unsigned long flags;unsigned int objsize;gfpflags &= gfp_allowed_mask;lockdep_trace_alloc(gfpflags);might_sleep_if(gfpflags & __GFP_WAIT);if (should_failslab(s->objsize, gfpflags))return NULL;local_irq_save(flags);c = get_cpu_slab(s, smp_processor_id());objsize = c->objsize;if (unlikely(!c->freelist || !node_match(c, node)))object = __slab_alloc(s, gfpflags, node, addr, c);else {object = c->freelist;c->freelist = object [c->offset];stat(c, ALLOC_FASTPATH);}local_irq_restore(flags);if (unlikely((gfpflags & __GFP_ZERO) && object ))memset(object , 0, objsize);kmemcheck_slab_alloc(s, gfpflags, object , c->objsize);kmemleak_alloc_recursive(object , objsize, 1, s->flags, gfpflags);return object ;}

这里主要判断两个标志,WAIT和ZERO,和本文有关的关键代码就是

if (unlikely((gfpflags & __GFP_ZERO) && object))

memset(object, 0, objsize);

3、vmalloc

vmalloc用于申请较大的内存空间,虚拟内存是连续。申请的内存的则位于vmalloc_start~vmalloc_end之间,与物理地址没有简单的转换关系,虽然在逻辑上它们也是连续的linux 用户空间内存申请,但是在物理上它们不要求连续。

以字节为单位进行分配linux 用户空间内存申请,在

4、kmalloc、get_free_page和vmalloc的区别:

我们用下面的程序来演示kmalloc、get_free_page和vmalloc的区别:

include5、malloc

malloc内存分配和Kmalloc相似,除非被阻塞否则他执行的速度非常快,而且不对获得空间清零。

malloc分配的是用户的内存。

使用 void *malloc(size_t size)

本文参考资料:

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: linux系统 初始化 物理内存
最后更新:2022年12月2日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
查看系统版本 linux “”的有关知识,不少人都会遇到这样的困境 Linux在内核中是如何记录进程资源的?你能从C语言源代码层面分析下吗? 【】原操作系统配备内核源代码,更不能进行内核模块实验 【Linux基础知识】与文件权限管理的Linux关系 linux/管理员管理员发布于5年前34(图) Linux和Unix操作系统之间有区别但也有联系?(一) Ubuntu系统如何升级和更新Linux内核版本?将推荐 Linux内核技术组成、组织和重要的数据结构等(组图) 【报错日志】一下升级linux内核的启动顺序为0 Linux终端窗口中输入mysql-V以显示MySQL版本信息sky 计算机操作系统全新版装系统盘点、理念与系统的优缺点 linux中常用的用户管理命令:1groups?列出当前用户所属 Linux下如何设置开机启动启动脚本?学算法 Linux中已经安装好了mysql命令 Linux系统用户系统上的三种类型的帐户的介绍 Linux下的开机启动设置方法是什么?脚本或服务 谷歌更新Linux内核构建的公共内核库:添加对kokoro作业的支持 linux下mysql中可以使用REVOKE语句来删除某个用户的权限 内核的角度来看,调用hotplug和通常的hotplug环境 Linux系统在开机的时候自动加载某些脚本或系统服务
Linux5.12的推送请求不断涌入新开放的合并窗口预计4月底看到它的稳定版本go语言被称作互联网时代的c语言,用来开发嵌入式linux的理由腾讯云服务器上也搭建一套环境,安装成功自动启动个人笔记本安装Ubuntu20.04LTS下载地址启动第一步--加载BIOS当你打开计算机电源(组图)虚拟机安装Ubuntu操作系统-Ubuntu空间20G镜像下载指令中各个make-C~/linuxM=`pwd编译Linux启动过程中的几个部分内核的引导(图)如何在Linux上安装虚拟机的结果大多都是怎么安装的一个免费软件时间跟进的小白鼠是什么鬼?专题计算机是如何启动的?、内核操作系统的启动流程学习Linux最简单、最实用的环境就是虚拟机环境(上)基于命令修改文件的权限命令-ld1.Linux磁盘分区和目录Linux发行版本之间的差别很少?国内性价比很高的Linux虚拟主机系统安装的流程是什么?Linux下修改文件权限的权限与所有权的实现就显得很有必要linux到底难不难学呢?推荐可以查看Linux命令大全Linux中修改文件权限的命令、创建者所在组、所有人Linux的内核放在了哪里?/boot的启动目录一览阿里云>社区>主题地图S>查看存储推荐
11种笔测试工具检测漏洞并准确模拟网络攻击ProPro 娃白天睡觉不太踏实,搞一个局域网实时监控,怎么办? tarLinux下的归档使用工具,用来打包和备份。 centos系统版本详细信息解决方案与操作系统版本兼容的重要性分析 Ubuntu和其他Linux中安装最新的LibreOffice版本的快速指南 Linux下程序的存放目录和安装目录 Linux下如何设置开机启动启动脚本?学算法 linux/管理员管理员发布于5年前34(图) Python都有哪些应用,学习完成Python后能的工作方向 解决ssh连接提示(A,突然连不了了) 查看系统版本 linux “”的有关知识,不少人都会遇到这样的困境 新公司的测试机磁盘空间空余很小简要记录以备忘 Linux中的用户权限管理方式 hello_exit函数代码存放在__init段中(一) VR物联网智能家居实训套件你能get的技能精致并不是 bash:批量修改文件名称的方法总结(一)-苏州安嘉 【每日一题】Linux链接文件- Linux一模一样远程连接编辑的操作图是什么? 老男孩教育怎么样有哪些课程?-八维教育 Linux5.12的推送请求不断涌入新开放的合并窗口预计4月底看到它的稳定版本
标签聚合
电脑 命令模式 文件目录 linux服务器 sudo 软件 shell 虚拟机 unix linux系统
书籍
课程
技术群
技术干货大合集↓
  • 2023年2月 / 26篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.