进程的内存布局与进程的虚拟地址空间

进程的内存布局

历史沿袭至今,C 语言程序一直都是由以下几部分组成的:

⚫ 正文段。也可称为代码段,这是 CPU 执行的机器语言指令部分,文本段具有只读属性,以防止程序由于意外而修改其指令;正文段是可以共享的,即在多个进程间也可同时运行同一段程序。

⚫ 初始化数据段。通常将此段称为数据段,包含了显式初始化的全局变量和静态变量,当程序加载到内存中时,从可执行文件中读取这些变量的值。

⚫ 未初始化数据段。包含了未进行显式初始化的全局变量和静态变量,通常将此段称为 bss 段,这一名词来源于早期汇编程序中的一个操作符,意思是“由符号开始的块”(block started by symbol),在程序开始执行之前,系统会将本段内所有内存初始化为 0,可执行文件并没有为 bss 段变量分配存储空间,在可执行文件中只需记录 bss 段的位置及其所需大小,直到程序运行时,由加载器来分配这一段内存空间。

⚫ 栈。函数内的局部变量以及每次函数调用时所需保存的信息都放在此段中,每次调用函数时,函数传递的实参以及函数返回值等也都存放在栈中。栈是一个动态增长和收缩的段,由栈帧组成,系统会为每个当前调用的函数分配一个栈帧,栈帧中存储了函数的局部变量(所谓自动变量)、实参和返回值。

⚫ 堆。可在运行时动态进行内存分配的一块区域,譬如使用 malloc()分配的内存空间,就是从系统堆内存中申请分配的。

Linux 下的 size 命令可以查看二进制可执行文件的文本段、数据段、bss 段的段大小:

图 9.3.2 显示了这些段在内存中的典型布局方式,当然,并不要求具体的实现一定是以这种方式安排其存储空间,但这是一种便于我们说明的典型方式。

进程的虚拟地址空间

上一小节讨论了 C 语言程序的构成以及运行时进程在内存中的布局方式,在 Linux 系统中,采用了虚拟内存管理技术,事实上大多数现在操作系统都是如此!在 Linux 系统中,每一个进程都在自己独立的地址空间中运行,在 32 位系统中,每个进程的逻辑地址空间均为 4GB,这 4GB 的内存空间按照 3:1 的比例进行分配,其中用户进程享有 3G 的空间,而内核独自享有剩下的 1G 空间,如下所示:

学习过驱动开发的读者对“虚拟地址”这个概念应该并不陌生,虚拟地址会通过硬件 MMU(内存管理单元)映射到实际的物理地址空间中,建立虚拟地址到物理地址的映射关系后,对虚拟地址的读写操作实际上就是对物理地址的读写操作,MMU 会将物理地址“翻译”为对应的物理地址,其关系如下所示:

Linux 系统下,应用程序运行在一个虚拟地址空间中,所以程序中读写的内存地址对应也是虚拟地址,并不是真正的物理地址,譬如应用程序中读写 0x80800000 这个地址,实际上并不对应于硬件的 0x80800000这个物理地址

为什么需要引入虚拟地址呢?

计算机物理内存的大小是固定的,就是计算机的实际物理内存,试想一下,如果操作系统没有虚拟地址机制,所有的应用程序访问的内存地址就是实际的物理地址,所以要将所有应用程序加载到内存中,但是我们实际的物理内存只有 4G,所以就会出现一些问题:

当多个程序需要运行时,必须保证这些程序用到的内存总量要小于计算机实际的物理内存的大小。

⚫ 内存使用效率低。内存空间不足时,就需要将其它程序暂时拷贝到硬盘中,然后将新的程序装入内存。然而由于大量的数据装入装出,内存的使用效率就会非常低。

⚫ 进程地址空间不隔离。由于程序是直接访问物理内存的,所以每一个进程都可以修改其它进程的内存数据,甚至修改内核地址空间中的数据,所以有些恶意程序可以随意修改别的进程,就会造成一些破坏,系统不安全、不稳定。

⚫ 无法确定程序的链接地址。程序运行时,链接地址和运行地址必须一致,否则程序无法运行!因为程序代码加载到内存的地址是由系统随机分配的,是无法预知的,所以程序的运行地址在编译程序时是无法确认的。

针对以上的一些问题,就引入了虚拟地址机制,程序访问存储器所使用的逻辑地址就是虚拟地址,通过逻辑地址映射到真正的物理内存上。所有应用程序运行在自己的虚拟地址空间中,使得进程的虚拟地址空间和物理地址空间隔离开来,这样做带来了很多的优点:

⚫ 进程与进程、进程与内核相互隔离。一个进程不能读取或修改另一个进程或内核的内存数据,这是因为每一个进程的虚拟地址空间映射到了不同的物理地址空间。提高了系统的安全性与稳定性。

在某些应用场合下,两个或者更多进程能够共享内存。因为每个进程都有自己的映射表,可以让不同进程的虚拟地址空间映射到相同的物理地址空间中。通常,共享内存可用于实现进程间通信。

⚫ 便于实现内存保护机制。譬如在多个进程共享内存时,允许每个进程对内存采取不同的保护措施,例如,一个进程可能以只读方式访问内存,而另一进程则能够以可读可写的方式访问。

⚫ 编译应用程序时,无需关心链接地址。前面提到了,当程序运行时,要求链接地址与运行地址一致,在引入了虚拟地址机制后,便无需关心这个问题。

参考资料:

1. 【正点原子】I.MX6U嵌入式Linux C应用编程指南V1.4

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

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

相关文章

精读《React Conf 2019 - Day1》

1 引言 React Conf 2019 在今年 10 月份举办,内容质量还是一如既往的高,如果想进一步学习前端或者 React,这个大会一定不能错过。 希望前端精读成为你学习成长路上的布道者,所以本期精读就介绍 React Conf 2019 - Day1 的相关内…

2024主流测试工具测评,总有一款适合你!

大家好!我是测试元宝~ 在软件开发周期中,测试是确保产品质量的关键环节。随着企业对于软件质量的要求日益提升,测试人员面临着前所未有的挑战,“工欲善其事必先利其器”,选择一款高效、实用的软件测试工具&#xff0c…

LeetCode # 547. 省份数量

547. 省份数量 题目 有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。 省份 是一组直接或间接相连的城市,组内不含其他没有…

Git 基于ED25519、RSA算法生成 SSH 密钥

Git 基于ED25519、RSA算法生成 SSH 密钥 基于ED25519算法&#xff0c;生成密钥对命令如下&#xff1a; ssh-keygen -t ed25519 -C "邮箱地址"基于RSA算法&#xff0c;生成密钥对命令如下&#xff1a; ssh-keygen -t rsa -C "<注释内容>"基于ED255…

若依集成MybatisPlus步骤

目录 一、新建业务模块二、集成MybatisPlus三、测试 一、新建业务模块 新建Maven模块&#xff0c;并建立如下目录 新模块的pom.xml添加如下内容 <description>业务模块</description><dependencies><!-- Mysql驱动包 --><dependency><groupI…

Locust中wait_time中匿名函数使用方法浅析

前言 翻出之前做个压测项&#xff0c;看到locust中对等待时间的实现方式感到好奇&#xff0c;于是总结下来。 源代码实现 def between(min_wait, max_wait):"""Returns a function that will return a random number between min_wait and max_wait.Example:…

thinkphp学习12-数据库的时间查询

传统方式 可以使用>、<、>、<来筛选匹配时间的数据&#xff1b; public function index() {$res Db::name(user)->where(create_time, >, 2018-1-1)->select();dump($res); }可以使用 between 关键字来设置时间的区间&#xff1b; public function in…

如何在Linux系统部署MeterSphere服务并配置固定公网访问地址

文章目录 推荐 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#…

影响APP广告变现收益的4个关键因素

APP的广告收入&#xff08;IAA&#xff09;展示 * eCPM/1000 IAA收入其实是由广告总展示量和每次展示的平均收入共同决定的。所以&#xff0c;提高IAA收入&#xff0c;我们需要双管齐下&#xff1a;同时提高广告总展示量和平均每次展示的收入。 app广告变现对接点击⬇️链接&…

单机版openstack安装

说明&#xff1a; 本文环境&#xff1a;CentOS 7 x64位 1.创建虚拟机 2.在虚拟机中安装 centos 7&#xff08;最小安装&#xff09;&#xff0c;修改主机名&#xff1a;openstack&#xff0c;设置 root 密码&#xff1a;12345678 3. 网卡设置&#xff0c;重启网络服务&#…

20240306-1-大数据的几个面试题目

面试题目 1. 相同URL 题目: 给定a、b两个文件&#xff0c;各存放50亿个url&#xff0c;每个url各占64字节&#xff0c;内存限制是4G&#xff0c;让你找出a、b文件共同的url&#xff1f; 方案1&#xff1a;估计每个文件的大小为50G64320G&#xff0c;远远大于内存限制的4G。所以…

VUE前端问题

一、图表内容不显示 watch: {chartData3: {handler() {this.init();},},timeData3: {handler() {this.init();},},}, 添加上面代码可以动态监控数据&#xff0c;实现图表的展示。 二、背景图片报错显示不出来 解决方法&#xff1a; background: url(~/assets/login/e.png) …

Day23:安全开发-PHP应用后台模块SessionCookieToken身份验证唯一性

目录 具体安全知识点 身份验证-Cookie使用 身份验证-Session使用 唯一性判断-Token使用 总结 源码 思维导图 PHP知识点&#xff1a; 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&…

Mysql date_format 格式化时间输出

网上的文章都是列一个大而全的表格&#xff0c;还有错误&#xff0c;我完全用不到那么多形式。遂自己开篇文章记录。 把datetime格式化为形如 2024-12-15 18:59:59的形式&#xff1a; %Y-%m-%d %H:%i:%S# 日期格式化输出select date_format(now(),%Y-%m-%d %H:%i:%S) time1,no…

C语言指针总结(完结篇)

前言 这篇博客终于迎来了指针博客的大结局&#xff0c;本篇主要分析习题来回顾之前的指针总结的知识点&#xff0c;这篇博客的题有点绕&#xff0c;哈哈算是经典了 个人主页&#xff1a;小张同学zkf 若有问题 评论区见 感兴趣就关注一下吧 目录 1. sizeof和strlen的对比 1.1 …

开源爬虫技术在金融行业市场分析中的应用与实战解析

一、项目介绍 在当今信息技术飞速发展的时代&#xff0c;数据已成为企业最宝贵的资产之一。特别是在${industry}领域&#xff0c;海量数据的获取和分析对于企业洞察市场趋势、优化产品和服务至关重要。在这样的背景下&#xff0c;爬虫技术应运而生&#xff0c;它能够高效地从互…

企业级数字人形象自定义解决方案

在品牌传播、线上营销等领域&#xff0c;一个独特且符合企业形象的数字人形象&#xff0c;无疑能为企业带来更强的品牌识别度和市场竞争力。美摄科技&#xff0c;作为业界领先的数字人形象解决方案提供商&#xff0c;凭借多年的技术积累和深厚的行业经验&#xff0c;推出了一套…

Linux第68步_旧字符设备驱动的一般模板

file_operations结构体中的函数就是我们要实现的具体操作函数。 注意&#xff1a; register_chrdev()和 unregister_chrdev()这两个函数是老版本驱动使用的。现在新字符设备驱动已经不再使用这两个函数&#xff0c;而是使用Linux内核推荐的新字符设备驱动API函数。 1、创建C…

公众号公司主体变更如何操作?

公众号迁移有什么用&#xff1f;只能改主体吗&#xff1f;好多朋友都想做公众号迁移&#xff0c;但是又不太清楚具体有啥用&#xff0c;今天我就来详细说说。首先&#xff0c;公众号迁移最重要的作用就是可以修改主体。比如你的公众号原来是 A 公司的&#xff0c;现在 A 公司不…