浅析Linux进程地址空间

这篇具有很好参考价值的文章主要介绍了浅析Linux进程地址空间。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

现代处理器基本都支持虚拟内存管理,在开启虚存管理时,程序只能访问到虚拟地址,处理器的内存管理单元(MMU)会自动完成虚拟地址到物理地址的转换。基于虚拟内存机制,操作系统可以为每个运行中的进程创建独享的虚拟地址空间,在这个空间中执行的程序,无法感知系统中其它进程的存在,从而使得不同的进程在运行时可以互不干扰。

进程地址空间的大小

虚拟地址空间的最大长度与系统中实际可用的物理内存数量无关,而是取决于硬件平台支持的寻址空间大小,即处理器的位数。32位处理器平台下,支持的虚拟地址空间范围为0x00000000~0xFFFFFFFF,总大小为2^32 字节,即4GB;而在64位处理器平台上,虚拟地址空间的范围从0x0000000000000000扩展到了0xFFFFFFFFFFFFFFFF,总大小为2^64 字节。用户进程通常无法直接访问全部地址空间,操作系统会将一部分地址空间划分给内核程序,具体的划分策略依赖于操作系统的实现。

进程地址空间的布局

下图是在典型的32位和64位Linux操作系统上,运行时进程的地址空间布局:
浅析Linux进程地址空间,# 内存管理,linux,服务器,运维

基于内核的管理策略,进程虚拟地址空间并没有全部分配给进程使用。Linux将进程地址空间划分成两个部分:位于高地址部分的内核地址空间和位于低地址部分的用户地址空间,其中

  • 内核地址空间:内核总是驻留在内存中,是操作系统的一部分。内核空间专为内核保留,并且对于系统中所有的进程都是相同的。内核空间只允许具备高特权级的内核程序进行访问;对于用户程序,只能通过系统调用等方式陷入内核空间中以访问系统提供的资源;
  • 用户地址空间:进程只能访问用户地址空间。用户地址空间保存了用户程序的运行指令和数据。内核在创建进程时,会依据用户可执行文件中提供的信息在用户空间中创建必要的区域,并为用户进程维护环境变量、堆和栈等信息。对于系统中的每个进程,其用户地址空间是彼此分离,完全隔绝的,进程只能访问属于自己的用户地址空间部分的数据

用户地址空间区域

由上图可以看出,无论是32位系统或是64位系统,进程用户地址空间除了地址空间大小不同外,内存布局基本相同,通常都包含以下几个部分:

  • 当前运行程序的二进制代码,对应于代码段;
  • 存储只读数据和可读写数据的段,如常量和全局变量;
  • 用于动态分配内存的堆;
  • 存储局部变量以及实现过程调用的栈;
  • 保存命令行参数和环境变量的区域。

内存映射区域

图中有一个特殊的区域没有画出,就是内存映射区域。内存映射区域通常位于堆和栈之间,用于将磁盘中的内容直接映射到内存中进行访问。Linux系统中的程序可以通过mmap系统调用来请求这种功能,相较于直接读写磁盘文件,内存映射提供了一种更加高效的文件IO方式,典型的应用场景就是动态库的装载。

进程地址空间访问

尽管系统中每个进程都拥有巨大的虚拟地址空间,实际可使用的物理内存确是有限的,因此内核必须考虑如何合理地安排有限的物理地址到虚拟地址空间区域的映射。Linux内核为每个进程维护了独立的进程页表,并管理着系统中所有的物理内存,通过动态建立虚拟地址和物理地址的页表映射,每个进程只会访问所需要的那一部分物理内存,从而实现了内存的高效使用。下图简要显示了进程虚拟地址空间中的地址到实际物理地址的转换过程:
浅析Linux进程地址空间,# 内存管理,linux,服务器,运维

缺页异常

内核遵循按需分配的原则,在进程实际需要某个虚拟内存区域的数据之前,内核不会为其建立虚拟内存到物理内存的页面映射。若进程访问的虚拟地址空间部分没有与具体的物理页帧建立关联,处理器会自动触发缺页异常,并调用内核设置的缺页异常处理函数进行处理。内核缺页异常处理函数会检测触发缺页异常的虚拟地址合法性,并在通过后,为其分配物理页帧和建立页面映射关系,并返回重新执行触发异常的指令。

非法内存访问

完整的进程地址空间被划分成了不同的区域,对于不同的区域,其设置的访问权限也都不相同,这同时也就意味着,用户程序在随意访问了某个内存地址时,如内核空间部分的部分,则可能触发不可恢复的错误。典型的几种访问了非法地址的情况如下所示:文章来源地址https://www.toymoban.com/news/detail-809366.html

  • 内核空间区域:内核空间区域对应的页表项,设置了高特权级访问权限,对于运行在低特权级的用户程序来说,是没有资格访问的;
  • 只读权限区域:只读权限的区域包含代码段、只读数据段以及其它被设置了只读权限的区域,如果对这类区域进行写操作,则会触发异常;
  • 极低地址区域:大部分操作系统中,都不允许进程访问极小的内存地址,对应于地址空间中保留未用的部分区域。也正因如此,C语言中NULL宏默认被定义成0,访问NULL指针则会触发空指针异常;
  • 未分配的区域:堆和栈之间的区域默认情况下,内核没有分配给进程使用。若用户在没有申请该段区域的情况下进行访问,会导致错误。

相关参考

  • 《深入理解Linux内核架构》
  • 《程序员的自我修养—链接、装载与库》

到了这里,关于浅析Linux进程地址空间的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】程序地址空间?进程地址空间

    了解进程的运行:  运行结果:我们会发现这打印的结果乱七八糟,因为它也不知道什么时候该干什么  我们让代码睡眠1秒:打印的结果就正常了  以前我们学习的内存管理(程序地址空间):  为了验证上面虚拟地址,我们运行下面代码: (这种问题出现的原因在下面的为

    2024年02月13日
    浏览(94)
  • Linux: 进程地址空间究竟是什么?进程地址空间存在意义何在?

     在C/C++中,我们常将内存分为: 代码区、常量区、全局区(静态区)、堆、栈 等等。相关内存区域划分如下:(X86, 32位平台) 如何验证C/C++中各区域的相对位置呢?  我们可以在每个区域中选择一个地址来验证C/C++中各区域的相对位置!!具体如下: 【源代码】: 【运行

    2024年04月08日
    浏览(75)
  • Linux之进程(四)(进程地址空间)

    目录 一、程序地址空间 二、进程地址空间 1、概念 2、写时拷贝 3、为什么要有进程地址空间 四、总结 我们先来看看下面这张图。这张图是我们在学习语言时就见到过的内存区域划分图。  下面我们在Linux下看一看内存区域是不是也是这么划分的。 可见在Linux下也是符合上面

    2024年02月04日
    浏览(41)
  • 【Linux】进程周边006之进程地址空间

      👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.程序地址空间 1.1验证地址空间的排布  1.2利用fork函数观察当子进程修改某个共

    2024年02月04日
    浏览(40)
  • 【Linux】进程>环境变量&&地址空间&&进程调度

    主页: 醋溜马桶圈-CSDN博客 专栏: Linux_醋溜马桶圈的博客-CSDN博客 gitee :mnxcc (mnxcc) - Gitee.com 目录 1.环境变量 1.1 基本概念 1.2 常见环境变量  1.3 查看环境变量方法  1.4 和环境变量相关的命令 1.5 环境变量的组织方式 1.6 通过代码如何获取环境变量 1.6.1 命令行第三个参数 1

    2024年04月15日
    浏览(54)
  • 【Linux】理解进程地址空间

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 ​我们在学习C语言的时候,都学过内存区域的划分如栈、堆、代码区、数据区这些。但我们其实并不真正理解内存 — 我们之前一直说的内存是物理上的内存吗? 我们先看一段测试代码: 运行结果: 我们可以注意到子进程的变量

    2024年02月02日
    浏览(53)
  • 『 Linux 』进程地址空间概念

    在c/C++中存在一种 内存 的概念; 一般来说一个内存的空间分布包括 栈区 , 堆区 , 代码段 等等; 且内存是 自底向上 (由 0x00000000 至 0xFFFFFFFF ); 以该图为例: 该图即为常见的内存分布图; 正文代码段 正文代码段所存放的数据 一般为函数体的二进制代码 ; 已初始化数据区 已初始化

    2024年02月03日
    浏览(45)
  • 【Linux】—— 进程地址空间

    序言: 在上篇中,我们讲解了关于进程优先级的概念。本期,我将给大家介绍的是关于进程地址空间的话题。 目录 (一)程序地址空间回顾 (二)代码演示 (三)进程地址空间的引入 总结 我们在学习C/C++语言的时候,大家可能都见过这样的空间布局图: 一个程序有哪些

    2024年02月15日
    浏览(41)
  • Linux:进程地址空间

    目录 1.程序地址空间  2.进程地址空间 我们在讲C/C++语言的时候,32位平台下,我们见过这样的空间布局图 我们来验证一下这张图的正确性: 运行结果: 通过观察静态变量的位置,可以认为静态变量就是全局变量,只是静态变量只初始化一次,有作用域的限制。 这里栈区还

    2024年02月04日
    浏览(40)
  • 【Linux】深挖进程地址空间

    作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等 座右铭:松树千年终是朽,槿花一日自为荣。 目标:熟悉【Linux】进程地址空间 毒鸡汤:也许有一天,你发觉日子特别的艰难,那可能是这次的收获特别的巨大。 望小伙伴们点赞👍收藏✨加关注哟💕💕      

    2024年02月03日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包