【Linux】--程序地址空间

一、程序地址空间

下面我们先看一段代码的运行情况:

代码如下:

运行结果如下:

我们上面的代码是先创建一个全局变量,然后创建一个子进程,然后在子进程中对这个全局变量进行修改,然后我们的父进程的话就不会对其进行修改,然后我们将父子进程对于这个变量进行取地址,我们很惊奇的发现,其两个的地址是一样的。

那么我们就有疑问了,我们一个地址,怎么会有两幅面孔呢?

所以我们可以肯定的是,其访问的地址,肯定不是我们的真实的物理地址。

那么我们在这里就引入我们的一个新的概念,虚拟地址。

首先我们再复习一下:

进程=PCB数据结构对象+数据和代码

我们的操作系统创建一个进程的时候,会由进程中的task_struct结构体中的PCB指向这个虚拟地址,虚拟地址和物理内存地址之间,使用了一个页表进行映射,所以其虚拟地址和物理地址之间是可以互相映射的。

那么这么做的作用是啥呢?

就好比如我们去银行取钱,那么我们中间需要通过取款机,或者柜台人员一样,我们用户是无法直接去金库拿钱的吧,这是操作系统为了保护我们的物理内存的一种方式。

我们的内存中,是有很多的进程的,那么为了防止进程之间影响,所以这样操作。

那么这么做的好处就是我们的用户可以关心内存的实际布局,这个交给操作系统进行管理,我们只需要关心虚拟内存即可。

下面是我们的虚拟内存空间和物理内存之间通过页表进行联系的示意图:

页表的左边是虚拟地址的编码,右边的是物理内存对应的编码。

前面我们知道,创建一个进程,我们是先创建其内核数据结构,然后再加载数据和代码的,那么我们操作系统对于一些不着急运行的进程,那么会先不加载其数据和代码,等到要运行这个进程的时候才会将其数据和代码加载,这种就叫做懒加载。

我们创建一个子进程,子进程会和父进程共享数据和代码,在对于数据修改前,我们的页表中,对于虚拟地址和物理内存地址的映射中,其实还有一个内容,就是权限,其一开始,只能是只读的状态,然后当我们的子进程发生了数据的修改,那么物理内存就会进程报错反馈,那么操作系统此时就会立马进行反馈,然后就会在物理内存中申请一块空间,给子进程,这种叫做写时拷贝。

所以说,子进程和父进程的虚拟地址虽然一样,但是其真实的物理地址是不一样的。

相关推荐
NailiConveyor1 小时前
柔性物流方案如何适配工厂升级?自动化输送流水线定制要点
大数据·运维·自动化·制造·业界资讯
Lsetea1 小时前
Certbot webroot申请SSL证书总是404:Nginx挑战目录与路径映射检查
运维·nginx·https·ssl证书·certbot
如若1231 小时前
Windows SSH + Headscale/Tailscale 组网及免密登录完整配置教程
运维·windows·ubuntu·ssh·内网穿透
开开心心就好2 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
一枕槐安4872 小时前
大模型限流、重试、超时处理:API 调用健壮性方案
linux·服务器·php·大模型api·指数退避·限流控制·超时预算
黑十2 小时前
PyTorch 报 “no CUDA GPUs are available“ 怎么办?3 步排查
服务器·网络·人工智能·pytorch·python
西索斯coding2 小时前
gpt-image-2.5-sunburst 和 gemini-3.1-flash-image 差多少?60 组项目素材的成功成本评测框架
java·linux·gpt·ai
箓维2 小时前
应用层协议基础_序列化与反序列化
linux
李纲明2 小时前
WordPress 白屏或提示「出现了严重错误」:先开 WP_DEBUG 抓致命错误,再二分插件与主题
运维·php·debug·wordpress·白屏·插件冲突·devdiy
wuminyu2 小时前
Java字节码学习总结:字节码如何加载、解析和执行
java·linux·c语言·jvm·c++