【Linux进程】——进程的程序地址空间

news2025/3/28 10:44:48

目录

前言

1.程序地址空间

1.1区域划分

1.2程序地址空间的本质

1.3程序地址空间分配原则

2.数据寻找

2.1补充:进程挂起

结语


前言

  在Linux系统的神秘世界里,进程就像是一个个小工匠,各自忙碌地完成着不同的任务。你是否想过,每个进程在自己的“工作空间”——程序地址空间里,是如何有条不紊地管理数据、代码和各种资源的呢?这就如同每个人有自己的房间,里面摆放着不同的东西,每一个角落都有其特定的用途。对于想要深入了解Linux系统运行机制的朋友来说,探究进程的程序地址空间就像是拿到了一把打开理解操作系统内部奥秘的钥匙。今天,就让我们一起踏入这个充满趣味和挑战的领域,揭开Linux进程程序地址空间的神秘面纱。


1.程序地址空间

当一个程序开始运行,它的代码和数据都会被拷贝一份,放在内存空间中

那么这些代码和数据,具体在内存空间的哪里呢?——在程序地址空间当中

程序地址空间是操作系统在进程被创建后,为进程分配的一处内存空间,进程的代码和数据都将放在这一处内存空间上。

但实际上,这处内存空间,并不真实存在,是操作系统在画饼

幽默点讲,当进程被创建的时候,操作系统大手一挥,对这个新进程说道:"你是新人,这片内存空间是我给你的,足足有16个GB,你随便用!"

16个GB?可能吗?显然是不可能的。

操作系统为了节省空间,一开始给进程分配的内存空间并不真实存在,而是虚拟的

既然是虚拟的,为什么还是要这样分配?

这是在告诉进程,你最多可以拥有16GB,但我不会真正给你这么多!

操作系统对进程的内存分配,采用 需要就给 的策略

进程什么时候需要内存,操作系统什么时候给,而不是一开始就给一个固定的内存

因为进程在运行期间,需要多少内存,操作系统也不清楚,这种需要就给的策略,且满足了进程的需求,又不会让内存被浪费,碎片化。

举个例子:顶级富豪与私生子

有个顶级富豪,他资产过亿,有四个私生子

四个私生子都不知道彼此的存在,富豪分别找到他们

对他们说:"我是你的亲生父亲,我有十个亿,你是我唯一的继承人,将来这些都是你的!"

在这四个私生子眼中,他们就知道自己最大的财富将会达到十个亿

其中一个私生子对富豪说:“我现在有点困难,你能救济一下我吗?给我XX”

这个XX,会是十个亿吗?

如果是,富豪也不会满足的,因为他只有十个亿,他不可能满足如此荒唐的要求,但给个几十万还是小意思。

在这个例子中,富豪相当于操作系统,四个私生子相当于进程们

  • 富豪给私生子画饼,就是操作系统给进程分配程序地址空间
  • 富豪满足私生子的要求,就是操作系统在不断给进程分配真实空间

操作系统会对每个进程说,有多少内存,但真正给起来,是挤牙膏一样地给

操作系统这种 需要则给 的内存分配策略,是为了防止内存被浪费,碎片化

1.1区域划分

操作系统给进程的程序地址空间,一般长这样

我们可以清晰地看到,这个空间是被划分了几个区域,分为堆、栈、代码区等,不同的数据将存储在不同的区域当中,互不干扰

为什么要划分?

区域划分是为了保护进程数据安全

如代码是只能读,不能写的,为了保证百分百的代码安全,操作系统就会将其保护起来,不允许进程修改,同样,对待其他的区域初衷也是如此

1.2程序地址空间的本质

内存中,会有很多进程,也就会有很多程序地址空间

面对数量庞大的程序地址空间,操作系统如何管理——先描述,再组组织

  • 先描述:操作系统会为每一个进程的程序地址空间都创建一个结构体对象
  • 再组织:将这些结构体对象通过某种数据结构集合在一起,或者直接与进程的PCB建立映射

程序地址空间的本质,也不过只是一个内核数据结构罢了

struct mm_struct {
unsigned long code_start; // 代码区起始地址
unsigned long code_end; // 代码区结束地址
unsigned long init_start; // 初始化区起始地址
unsigned long init_end; // 初始化区结束地址
unsigned long uninit_start; // 未初始化区起始地址
unsigned long uninit_end; // 未初始化区结束地址
unsigned long heap_start; // 堆区起始地址
unsigned long heap_end; // 堆区结束地址
unsigned long stack_start; // 栈区起始地址
unsigned long stack_end; // 栈区结束地址
};

1.3程序地址空间分配原则

当进程需要新创建一个变量,操作系统就会根据这个变量的类型,将符合其特征的一块区域的地址分配给它

例如:如果一个指针存储malloc申请的空间地址,那它指向的地址就是堆区;如果是一个字符串常量,该常量的地址就是在代码区

每个区的空间分配也是有讲究的,并不是有就分配,随意分配

分配规律:

  • 堆区分配空间向上增长,先分配的空间地址比后分配的空间地址小
  • 栈区分配空间,遵循全局向下增长,局部向上增长

堆区好理解,但栈区还是需要好好说一下

  • 全局向下增长,是指如果你连续创建多个单体变量,这些变量的地址是越来越小的。
  • 局部向上增长:如果创建的是数组,结构体这样内部有数据元素的,那么他们内部的元素地址是越来越大

例如:int arry1[2] 和 int arry2[2]

arry1 的地址比 arry2 的地址高(全局向下分配)

arry1[0] 的地址比 arry1[1] 的地址低(局部向上分配)

2.数据寻找

操作系统给你分配的程序地址空间是假的,是虚拟的?那么我们平常打印的地址呢?

在进程fork中,我们就已经认识到,一个变量会有两个不同的值

如果进行深究,在子进程和父进程中分别打印出一个变量的地址,你会发现一个震惊的现象,同一个地址,居然会有两份不一样的值

学到今天就会知道,这个地址,肯定不是物理地址,而是操作系统给我们的虚拟地址

程序地址空间上的地址是虚拟的

我们打印,在表面看到的地址就是程序地址空间上的虚拟地址,而真实的地址,其实需要通过操作系统为进程分配的页表来找到

页表,也是内核中的众多数据结构之一,它是一张记录虚拟地址和物理地址映射关系的一张表。

当程序被加载到内存空间的时候,其代码和数据会优先在内存空间中找到自己的位置,操作系统会记录该位置,然后创建PCB,创建程序地址空间,创建页表并建立虚拟地址和物理地址的映射

浅浅看一下页表内容

 

内容说明

  1. 虚拟地址和物理地址的映射关系
  2. 分配检查物理地址是否已经被其他进程占用
  3. 内容位检查物理地址当中是否已经有内容
  4. 读写位表示是否可以读写,或只读只写 

注意:其中分配位和内容位只有两种状态,0和1

进程得到变量具体数据的过程

  1. 拿到变量的虚拟地址
  2. 通过页表的映射关系找到物理地址
  3. 通过物理地址在内存中找到对应的值

即虚拟地址——物理地址——真实数据的数据寻找方式,现在我们就可以解答,为什么fork函数的返回值是两个不同的值,却又有相同的地址

它们的虚拟地址一样,但物理地址不一样,值也就不一样

  • 打印的地址是虚拟地址,所以是一样的
  • 而值是物理地址对应的值,所以值是不一样的

一开始可能觉得麻烦,但熟悉起来,就会发现这种数据寻找方式有诸多的妙处,例如

  1. 进程以统一的视角看待内存,任意一个进程,可以通过 地址空间+页表 就可以将乱序的内存数据,变成有序、分门别类地规划好
  2. 存在虚拟地址空间,可以有效地进行进程访问内存的安全检查,读写位保护内存安全
  3. 将进程管理和内存管理进行解耦
  4. 通过页表,让进程映射到不同的物理内存中,并且分配位保护物理内存,从而实现进程的独立性

2.1补充:进程挂起

如果一个进程被挂起,它的代码和数据都会被调出到磁盘中,内存中就不再有这些代码和数据,即我们将页表当中的存储进程代码和数据的物理地址的分配位改为 0 ,就代表进程没有被分配物理内存,就是被挂起了


结语

  Linux进程的程序地址空间是整个Linux系统高效稳定运行的关键所在。理解它不仅能帮助我们解决实际工作中遇到的各种问题,还为我们在系统开发、优化和安全管理等方面提供了坚实的基础。随着技术的不断发展,对进程程序地址空间的研究和应用也将不断深入。让我们持续关注这个领域,探索更多的可能性。

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

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

相关文章

边缘云原生操作系统的设计与思考

资料来源:火山引擎-开发者社区 边缘云行业现状和发展历程 从 06 年 AWS 推出 EC2 、S3 到今天已经过去了 18 年,云计算早已不是一个新鲜词汇,从当前业务来看,我们能看到云计算从中心到中心边缘的发展趋势,为什么会有 这…

Jenkins muti-configuration-project 中调用pipeline project

Jenkins muti-configuration-project 中调用pipeline project 解决方案示例练习1. 多配置项目设置:2. 触发器配置:3. Pipeline 项目 Jenkinsfile: 解决方案 创建多配置项目: 在 Jenkins 中创建一个新的多配置项目。在“配置矩阵…

AI学习——卷积神经网络(CNN)入门

作为人类,我们天生擅长“看”东西:一眼就能认出猫狗、分辨红绿灯、读懂朋友的表情……但计算机的“眼睛”最初是一片空白。直到卷积神经网络(CNN)​的出现,计算机才真正开始理解图像。今天,我们就用最通俗的…

双指针算法-day14(分组循环)

1.最长奇偶子数组 题目 解析 分组循环模板: 简单来说: 第一步:指针遍历找到满足条件的开头下标,并用 start i 记录开头;第二步:指针不断右移寻找满足条件的最长子数组;第三步:更新…

Linux基础开发工具--gdb的使用

目录 安装准备: 1. 背景 2. 开始使用 3. 做一个Linux第一个小程序-进度条 安装准备: 对于gdb的学习使用,为了方便大家学习,我建议大家先安装一个cgdb进行学习,这样方便观察操作与学习gdb。 用以下…

RabbitMQ的高级特性介绍(一)

消息确认机制 ⽣产者发送消息之后, 到达消费端之后, 可能会有以下情况: a. 消息处理成功 b. 消息处理异常 RabbitMQ向消费者发送消息之后, 就会把这条消息删掉, 那么第二种情况, 就会造成消息丢失。 那么如何确保消费端已经成功接收了, 并正确处理了呢? 为了保证消息从队列…

QML开发入门1--安装QT6.8和新建第一个QtQuickApplication

1.下载在线安装工具 qt-online-installer-windows-x64-4.8.1.exe 2.安装 注:可能官网qt安装很慢。需要使用国内镜像源。推荐阿里镜像 qt-online-installer-windows-x64-4.8.1.exe --mirror https://mirrors.aliyun.com/qt3.配置QT关键配置 3.1 无法编译 注&#…

如何让节卡机器人精准对点?

如何让节卡机器人精准对点? JAKA Zu 软件主界面主要由功能栏、开关栏、菜单栏构成。 菜单栏:控制柜管理,机器人管理与软件管理组成。主要功能为对控制柜关机、APP 设置、机器人本体设 置、控制柜设置、连接机器人和机器人显示等功能。 开关…

在 Spring Boot 中调用 AnythingLLM 的发消息接口

整体逻辑: 自建系统的web UI界面调用接口: 1.SpringBoot接口:/anything/chatMessageAnything 2.调用anythingLLM - 调用知识库deepseek r1 . Windows Installation ~ AnythingLLMhttps://docs.anythingllm.com/installation-desktop/windows http://localhost:3…

[GHCTF 2025]Popppppp[pop链构造] [php原生类的利用] [双md5加密绕过]

题目 <?php error_reporting(0);class CherryBlossom {public $fruit1;public $fruit2;public function __construct($a) {$this->fruit1 $a;}function __destruct() {echo $this->fruit1;}public function __toString() {$newFunc $this->fruit2;return $new…

Tr0ll2靶机详解

一、主机发现 arp-scan -l靶机ip&#xff1a;192.168.55.164 二、端口扫描、漏洞扫描、目录枚举、指纹识别 2.1端口扫描 nmap --min-rate 10000 -p- 192.168.55.164发现21端口的ftp服务开启 以UDP协议进行扫描 使用参数-sU进行UDP扫描 nmap -sU --min-rate 10000 -p- 19…

制造业数字化转型,汽车装备制造企业数字化转型案例,智能制造数字化传统制造业数字化制造业数字化转型案例

《某制造业企业信息化整体解决方案》PPT展示了一个汽车装备企业的整体信息化解决方案&#xff0c;阐述了该企业的业务特点和现状&#xff0c;主要包括按订单生产、多级计划和产品跟踪等&#xff0c;分析了信息化建设的主要困难&#xff0c;如信息管理手工化、过程数据追溯困难、…

科技云报到:AI Agent打了个响指,商业齿轮加速转动

科技云报到原创。 3月16日&#xff0c;百度旗下文心大模型4.5和文心大模型X1正式发布。目前&#xff0c;两款模型已在文心一言官网上线&#xff0c;免费向用户开放。 同时&#xff0c;文心大模型4.5已上线百度智能云千帆大模型平台&#xff0c;企业用户和开发者登录即可调用AP…

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…

大白话读懂java对象创建的过程

1. java对象创建流程&#xff08;大白话版&#xff09; 咱们java对象被创建的过程大致如下&#xff0c;即&#xff1a; 在 JVM 中对象的创建&#xff0c;从⼀个 new 指令开始&#xff1a; 首先检查这个指令的参数是否能在常量池中定位到⼀个类的符号引用检查这个符号引用代表…

AI图像理解技术的演进

在CLIP等现代多模态模型出现之前&#xff0c;早期的图生文技术主要依赖人工标注的ImageNet等数据集&#xff0c;但其技术路线与当前方法存在本质差异。 一、传统图生文技术的标注依赖 ImageNet的核心地位 在2012-2020年间&#xff0c;ImageNet的1,400万张人工标注图像&#xff…

电脑节电模式怎么退出 分享5种解决方法

在使用电脑的过程中&#xff0c;许多用户为了节省电力&#xff0c;通常会选择开启电脑的节能模式。然而&#xff0c;在需要更高性能或进行图形密集型任务时&#xff0c;节能模式可能会限制系统的性能表现。这时&#xff0c;了解如何正确地关闭或调整节能设置就显得尤为重要了。…

【Java】——程序逻辑控制(构建稳健代码的基石)

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;【Java】内容概括 文章目录&#xff1a; 一.顺序结构二.分支结构1.if 语句1.1 语法格式11.2 语法格式21.3 语法格式3 …

卫星互联网智慧杆:开启智能城市新时代​

哇哦&#xff01;在当下这个数字化浪潮正以雷霆万钧之势席卷全球的超酷时代&#xff0c;智慧城市建设已然成为世界各国你追我赶、竞相发力的核心重点领域啦&#xff01;而咱们的卫星互联网智慧杆&#xff0c;作为一项完美融合了卫星通信与物联网顶尖技术的创新结晶&#xff0c;…

Qt-QChart实现折线图

一、介绍场景 动态查看数据变化&#xff0c;或者了解数据发展趋势&#xff0c;让数据可以形象直观展现出来&#xff0c;这里推荐使用折线图的方式展现&#xff0c;本文抛砖引玉&#xff0c;简单实现一个实例&#xff0c;效果图如下&#xff1a; 二、实现步骤 1、charts组件 …