【linux进程(七)】程序地址空间深度剖析

简介: 【linux进程(七)】程序地址空间深度剖析

1. 前言

由于此Linux系列文章偏向于做

顺序学习手册,所以有些内容在

一篇文章中可能不连贯,敬请谅解!

请先阅读下面的文章的最后一段
了解打印出来的地址并不是物理地址
这一事实逻辑:

程序地址空间前言

本章重点:

本篇文章着重讲解进程中的虚拟地址
和物理地址的关系,了解虚拟地址的
内核本质是什么,以及页表和物理地址
的映射逻辑和写时拷贝的具体体现,
期间我们将回答三个问题:

  • 什么是地址空间?
  • 地址空间是如何设计的?
  • 为什么要有地址空间?

2. 什么是程序地址空间?

在理解地址空间前,我们知道一个事实:

平时看见的地址并不是真实的地址

又叫虚拟地址,真实的地址空间

被称为物理地址(物理内存)

我想通过讲一个故事来帮助理解
到底什么是程序地址空间:

有一个富豪,它有10亿资产,由于
年轻时比较浪,所以他有四个私生子
这四个私生子并不知道彼此的存在,
私生子A是个医生,私生子B是个企业家
私生子C是个街头混混,私生子D是个学生
富豪分别对小A,B,C,D说:
(1),小A啊,你要是努力做个医生,以后我的
10亿美金都是你的了
(2),小B啊,要是你把你的公司运作的很好
以后我的10亿美金就是你的了
(3),小C啊…小D啊…

故事还没结束,有一天,A说:老爸
给我10万美金,我要买医疗器械,
富豪想了想觉得是正事,于是给了
小A十万美金,小C又说:老爸,给我
两千美金吧,我吃不起饭了,富豪一听
就把钱打过去了,所以我们知道,这四个
人都可以用10亿美金以内的钱,但是
永远用不到10亿美金!

现在列出人物和地址的对应关系:

  1. 富豪对应操作系统
  2. 10亿美金对应物理地址
  3. 私生子对应每一个进程
  4. 富豪画的饼对应地址空间

所以可以得出结论,地址空间可以
理解为操作系统给进程画的饼
它并不是真实的物理地址!


3. 程序地址空间是如何设计的?

既然富豪给每一个私生子都画了饼
所以对应每一个进程都又一个自己的
程序地址空间,这是第一个结论

然而,OS要管理这些空间,一定
要先组织,再管理!所以地址空间
是一个struct结构,**这是第二个结论**

再来看看程序地址空间的图:

程序地址空间无非就是各个
区域的结合,然而各个区域的划分
无非就是两个整数begin和end
一个在区域的开头,一个在区域的结尾
这是第三个结论!
如图:

根据上面的推论,我们可以得出结论:
地址空间这个北河数据结构中(struct)
至少包含了各个区域的划分,它的概念
结构如下:

struct addr_room
{
  int code_start;//代码区起始
  int code_end;//代码区结束
  int init_start;//初始化区起始
  int init_end;//初始化区结束
  int heap_start;//堆区起始
  int heap_end;//堆区结束
  ......
  其他属性
};

所谓的区域范围变化
实际上就是对start和end做加减!


4. 虚拟地址和物理地址的关联

当我们理解了什么是虚拟地址后,

现在再谈虚拟地址和物理地址的关系:

本质是一种映射关系!

现代计算机使用以下方法解决问题:
OS为每一个进程配对一个虚拟地址
空间和一张页表,要访问物理地址时,
需要先在页表进行映射,若访问的是
非法地址,则会在页表层阻止你的访问!

所以为什么一个地址会有两个值?

现在我们就能回答这个问题了:

创建子进程时,子进程的数据和
代码和父进程共享,也就是和父进程
一样,所以此时子进程的页表和程序
地址空间和父进程一样!当子进程尝试
修改变量的值时,操作系统会重新为子进程
开辟一份物理内存,并修改子进程页表的
映射关系,此时映射到物理内存的不同
区域,但是虚拟地址是一样的!

这个过程也叫写时拷贝


5. 页表的结构以及作用

修改常量字符串时编译器会报错,

是在哪个阶段报的错呢?

const char* p = "abcd";
*p = "123";

其实页表不仅仅只有映射关系

表这一个结构,它还附带了物理
内存中每一个区域的读写权限:

很明显,常量字符串对应的物理地址
区域的权限是只可读,所以当虚拟内存
去映射物理内存时,在页表层面发现你的
访问是权限不允许的,就会在页表层驳回
你的请求,也就是会报错!

所以页表可以起到安全评估

保护物理内存的作用!

这是页表的第一个作用

页表的第二个作用:

将无序变有序

虚拟地址在映射物理内存时
是不是随意映射的?就是说映射
到物理内存后的顺序是全乱的?
结论是当然不是!在页表层映射时
会将不同的数据类型进行划分
使得映射到物理内存后是比较
有序的一种状态!


6. 为什么要存在地址空间?

通过以下三个方面来说明

地址空间的作用:

  1. 有效的保护了物理内存

凡是非法的访问或者映射,os都
会识别到,并且终止你这个进程!
地址空间和页表都由OS创建并
进行管理,一切访问都要在OS的监管下!

  1. 使OS的耦合度更低

因为有地址空间和页表的存在,
物理内存可以不关心未来数据的
类型,可以直接对它进行加载,这样
物理内存的分配就可以和进程的管理
分开来,做到它们并没有任何关系,
所以内存管理模块和进程管理模块
就完成了解耦合的操作!

  1. 保证进程的独立性

因为有地址空间的存在,每一个进程
都认为自己拥有4GB的空间,并且各个
区域是有序的,进而可以通过页表映射
到不同的区域,来实现进程的独立性,
每一个进程不知道也不需要知道其他
进程的存在!!!


7. 总结以及拓展

关于Linux进程基础的内容就讲到

这里,下一章是全新的章节–进程控制

讲了这么久的理论了,怎么控制一个进程?

也就是创建,回收一个进程?有了前面

的基础铺垫后,后面的学习内容也就容易了

拓展阅读:

Linux中页表的内核代码


🔎 下期预告:Linux进程控制 🔍


相关文章
|
2天前
|
监控 Linux 应用服务中间件
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
|
3天前
|
算法 Linux 编译器
技术笔记:LINUX2.6.32下的进程分析
技术笔记:LINUX2.6.32下的进程分析
|
2天前
|
Web App开发 运维 监控
深入探索Linux命令pwdx:揭秘进程工作目录的秘密
`pwdx`命令在Linux中用于显示指定进程的工作目录,基于`/proc`文件系统获取实时信息。简单易用,如`pwdx 1234`显示PID为1234的进程目录。结合`ps`和`pgrep`等命令可扩展使用,如查看所有进程或特定进程(如Firefox)的目录。使用时注意权限、进程ID的有效性和与其他命令的配合。查阅`man pwdx`获取更多帮助。
|
3天前
|
监控 Linux
深入了解Linux的pmap命令:进程内存映射的利器
`pmap`是Linux下分析进程内存映射的工具,显示内存区域、权限、大小等信息。通过`/proc/[pid]/maps`获取数据,特点包括详细、实时和灵活。参数如`-x`显示扩展信息,`-d`显示设备。示例:`pmap -x 1234`查看进程1234的映射。注意权限、实时性和准确性。结合其他工具定期监控,排查内存问题。
|
3天前
|
网络协议 Linux Shell
技术笔记:Linux中的两种守护进程standalone和xinetd
技术笔记:Linux中的两种守护进程standalone和xinetd
|
3天前
|
缓存 Linux 编译器
技术笔记:Linux程序包管理
技术笔记:Linux程序包管理
|
3天前
|
监控 网络协议 关系型数据库
如何在Linux中查看正在运行的进程以及过滤特定端口和进程名称
如何在Linux中查看正在运行的进程以及过滤特定端口和进程名称
6 0
|
7天前
|
存储 Linux Shell
Linux进程概念(上)
冯·诺依曼体系结构概述,包括存储程序概念,程序控制及五大组件(运算器、控制器、存储器、输入设备、输出设备)。程序和数据混合存储,通过内存执行指令。现代计算机以此为基础,但面临速度瓶颈问题,如缓存层次结构解决内存访问速度问题。操作系统作为核心管理软件,负责资源分配,包括进程、内存、文件和驱动管理。进程是程序执行实例,拥有进程控制块(PCB),如Linux中的task_struct。创建和管理进程涉及系统调用,如fork()用于创建新进程。
26 3
Linux进程概念(上)
|
5天前
|
存储 Linux
【Linux】进程_2
【Linux】进程_2
8 3
|
3天前
|
存储 Shell Linux
Linux进程概念(下)
本文详细的介绍了环境变量和进程空间的概念及其相关的知识。
12 0
Linux进程概念(下)