Linux 进程地址空间

我们思考之前没有解答的一个问题的一个问题

就是为什么id可以是两个值???

https://blog.csdn.net/Starry_tsx/article/details/152663966?spm=1001.2014.3001.5501

运行结果是这样的

我们发现两个id同一个地址 并且值还不同

所以我们看到的这个地址肯定不是物理地址

那么这个地方是什么地址???

只可能是虚拟地址

那么实际物理地址呢

虚拟地址和物理地址有什么联系呢

虚拟地址和物理地址在页表中产生联系

页表存在于内存中

页表我们可以类似理解成一种映射关系

将我们的虚拟地址映射到物理地址上

有什么好处 或者说为什么呢

1.地址空间隔离:每个进程拥有独立的页表,对应专属的虚拟地址空间。

进程只能通过页表访问自己的虚拟地址,无法直接越界访问其他进程或内核的物理内存,实现了 "进程间内存互不干扰"。

2.内存访问保护:页表可设置权限标志(如 "只读""可写""执行禁止"),防止进程非法修改内存(如越权写其他进程的只读段),增强系统稳定性与抗攻击能力。

3.程序基于 "连续的虚拟地址空间" 编写,无需关心物理内存的实际分布(是否连续、物理地址具体值)。

编译时仅生成虚拟地址,运行时由操作系统通过页表动态映射物理地址,实现 "一次编译,多平台运行",降低了硬件差异对程序开发的影响。

4. 支持 "内存共享与复用",节省系统资源 多个进程可通过页表共享同一物理页帧(典型场景:共享库、进程间共享内存)。例如,多个进程使用 C 标准库时,只需将库的物理页帧映射到各进程的虚拟地址空间,无需在物理内存中加载多份副本,大幅节省内存占用。

那么 我们前面讲过子进程的写实拷贝

原本父进程和子进程公用一份数据

也共用一份页表

但是当我们对子进程数据进行操作时

为了保证进程的独立

我们会开空间把父进程的数据单独拷贝做修改

同时对子进程的页表拷贝但是虚拟地址不变

虚拟地址映射的物理地址变成了子进程开空间的地址

这也是为什么上面那个代码运行出来两个id的值不同但是地址相同

它们只是虚拟地址相同 物理地址不同 所以其值也不同

包括我们之前看到的很经典的一张图也是虚拟内存的图

那么进程如果这个进程重新排队后怎么找到页表呢???

有一个cr3的寄存器 存放着页表的地址

这个属于进程的硬件上下文 进程结束其数据会打包带走的

当这个进程再跑的时候 这个进程的页表地址覆盖掉cr3的地址

这样我们就可以找到页表了

接着再思考一个问题

我们知道虚拟内存地址有栈区 代码区等等 但是比如常量区是不能被修改的

页表是咋处理的?

页表会对不同的区域有其权限字段 比如说字符常量区 页表描述权限的字段就没有写的访问权限

当一个进程以写权限访问 这便是非法访问 操作系统就有可能会杀死这个进程

相关推荐
junnhwan3 小时前
【苍穹外卖笔记】Day05--Redis入门与店铺营业状态设置
java·数据库·redis·笔记·后端·苍穹外卖
Zzz 小生3 小时前
**编程基础学习(二)-C语言变量、控制结构和函数
笔记·学习
金水谣3 小时前
10.12考研笔记
笔记
撬动未来的支点3 小时前
【Linux】Linux驱动开发与BSP开发:嵌入式系统的两大基石
linux·驱动开发
fanged3 小时前
HarvardX TinyML小笔记3(番外6:视觉探测)(TODO)
笔记
摇滚侠3 小时前
Spring Boot 3零基础教程,Spring Boot 特性介绍,笔记02
java·spring boot·笔记
武清伯MVP3 小时前
阮一峰《TypeScript 教程》学习笔记——基本用法
笔记·学习·typescript
jz_ddk4 小时前
[LVGL] 从0开始,学LVGL:基础构建篇 - 掌握UI的核心构建块
linux·网络协议·ui·rpc·嵌入式·gui·lvgl
要做朋鱼燕4 小时前
STM32与W25Q64 SPI通信全解析
笔记·嵌入式·hal·spi