浅析Linux进程地址空间

前言

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

进程地址空间的大小

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

进程地址空间的布局

下图是在典型的32位和64位Linux操作系统上,运行时进程的地址空间布局:
在这里插入图片描述

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

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

用户地址空间区域

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

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

内存映射区域

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

进程地址空间访问

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

缺页异常

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

非法内存访问

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

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

相关参考

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/619929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ros2+gazebo(ign)激光雷达+摄像头模拟

虽然ign不能模拟雷达,但是摄线头是可以模拟的。 好了现在都不用模拟了,ign摄线头也模拟不了。 ros2ign gazebo无法全部模拟摄线头和雷达。 只能有这样2个解决方法: 方法1:使用ros2 gazebo11 方案2:使用ros2买一个实…

【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究

目录 主要内容 模型研究 结果一览 下载链接 主要内容 该模型以环境保护成本和运行成本为双目标构建了微电网优化调度模型,模型目标函数和约束条件复现文献《基于改进粒子群算法的微电网多目标优化调度》,程序的特点是采用非支配排序的蜣螂…

Redis缓存使用问题

数据一致性 只要使用到缓存,无论是本地内存做缓存还是使用 redis 做缓存,那么就会存在数据同步的问题。 以 Tomcat 向 MySQL 中写入和删改数据为例,来解释数据的增删改操作具体是如何进行的。 我们分析一下几种解决方案, 1、先更新缓存,再更新数据库 2、先更新数据库,…

2023年第十四届中国数据库技术大会(DTCC2023):核心内容与学习收获(附大会核心PPT下载)

随着信息化时代的深入发展,数据库技术作为支撑信息化应用的核心技术,其重要性日益凸显。本次大会以“数据价值,驱动未来”为主题,聚焦数据库领域的前沿技术与最新动态,吸引了数千名业界专家、企业代表和数据库技术爱好…

橘子学Spring01之spring的那些工厂和门面使用

一、Spring的工厂体系 我们先来说一下spring的工厂体系(也称之为容器),得益于大佬们对于单一职责模式的坚决贯彻,在十几年以来spring的发展路上,扩展出来大量的工厂类,每一个工厂类都承担着自己的功能(其实就是有对应的方法实现)…

阿里云云服务器u1实例和e实例有什么区别?

阿里云服务器u1和e实例有什么区别?ECS通用算力型u1实例是企业级独享型云服务器,ECS经济型e实例是共享型云服务器,所以相比较e实例,云服务器u1性能更好一些。e实例为共享型云服务器,共享型实例采用非绑定CPU调度模式&am…

监督学习 - 岭回归(Ridge Regression)

什么是机器学习 岭回归(Ridge Regression)是一种线性回归的扩展,它通过在损失函数中添加正则化项(L2范数)来解决线性回归中可能存在的过拟合问题。正则化项有助于限制模型的参数,使其不过分依赖于训练数据…

LeetCode264. 丑数 II(相关话题:多重指针动态规划)

题目描述 给你一个整数 n ,请你找出并返回第 n 个 丑数 。丑数 就是质因子只包含 2、3 和 5 的正整数。 示例 1: 输入:n 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。示例 2&am…

【Sharding-Sphere 整合SpringBoot】

Sharding-Jdbc在3.0后改名为Sharding-Sphere。Sharding-Sphere相关资料,请自行网上查阅,这里仅仅介绍了实战相关内容,算是抛砖引玉。 Sharding-Sphere 整合SpringBoot 一、项目准备二、项目实战1. pom.xml及application.yml2. OrderInfoCont…

串行Nor Flash的结构和参数特性

文章目录 引言1、Nor Flash的结构2、Nor Flash的类别3.标准Serial Nor Flash的特征属性1.Wide Range VCC Flash2.Permanent Lock3.Default Lock Protection4.Standard Serial Interface5.Multi-I/O6.Multi-I/O Duplex (DTR)7.XIP(片上执行) 4.标准Serial…

Java内置锁:深度解析Lock接口中lock方法和lockInterruptibly方法

Java11中的Lock接口提供lock()和lockInterruptibly()两种锁定方法,用于获取锁,但处理线程中断时有所不同,lock()使线程等待直到锁释放,期间无视中断;而lockInterruptibly()在等待中若收到中断请求,会立即响…

倍福PLC控制器开发环境介绍

倍福PLC控制器是一款功能强大、易于使用的可编程逻辑控制器,广泛应用于各种工业自动化控制系统中。为了充分发挥倍福PLC控制器的功能,需要使用合适的开发环境。下面将介绍倍福PLC控制器的开发环境,主要包括软件安装与配置、工程创建与管理、编…

“超人练习法”系列08:ZPD 理论

01 先认识一个靓仔 看过 Lev Vygotsky 这个人的书吗?他是一位熟练心理学家,对人们习得技能的方式非常感兴趣,但他 37 岁的时候就因肺炎英年早逝了。 他认为社会环境对学习有关键性的作用,认为社会因素与个人因素的整合促成了学习…

element ui el-table展示列表,结合分页+过滤功能

vueelement-ui实现的列表展示&#xff0c;列表分页&#xff0c;列表筛选功能 1&#xff0c;分页器 el-table模块下面是分页器代码 <el-pagination></el-pagination> <el-table></el-table> <!-- 分页器 --><div class"block" st…

力扣每日一练(24-1-13)

如果用列表生成式&#xff0c;可以满足输出的型式&#xff0c;但是不满足题意&#xff1a; nums[:] [i for i in nums if i ! val]return len(nums) 题意要求是&#xff1a; 你需要原地修改数组&#xff0c;并且只使用O(1)的额外空间。这意味着我们不能创建新的列表&#xff…

【QT】标准对话框

目录 1 概述 2 QFileDialog对话框 1.选择打开一个文件 2.选择打开多个文件 3&#xff0e;选择已有目录 4&#xff0e;选择保存文件名 3 QColorDialog对话框 4 QFontDialog对话框 5 QInputDialog标准输入对话框 1.输入文字 2&#xff0e;输入整数 3&#xff0e;输入…

Python教程(23)——Python类中常用的特殊成员

在Python中&#xff0c;类特殊成员是指以双下划线开头和结尾的属性和方法&#xff0c;也被称为魔术方法&#xff08;Magic methods&#xff09;或特殊方法&#xff08;Special methods&#xff09;。这些特殊成员在类的定义中具有特殊的语法和功能&#xff0c;用于实现对象的特…

【PlantUML】-类图-布局,如何改变元素位置

写在前面 PlantUML属于自动布局。掌握好&#xff0c;是一件利器&#xff0c;掌握不好&#xff0c;就会不知其所以然。尤其在布局方面&#xff0c;因为它的布局可能会和你想的不太一样。本篇文章以例子为基础&#xff0c;简单地说几个在实际应用过程中摸索出来的原则。相信看完这…

【猫头虎分享】全面揭秘鸿蒙4.0:华为的技术革新与市场影响

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

逆变器3前级推免(高频变压器)

一节电池标压是在2.8V—4.2V之间&#xff0c;所以24V电压需要大概七节电池串联。七节电池电压大概在19.6V—29.4V之间。 从24V的电池逆变到到220V需要升压的过程。那么我们具体需要升压到多少&#xff1f; 市电AC220V是有效值电压&#xff0c;峰值电压是220V*1.414311V 如果…