进程地址空间

进程的虚拟地址空间由操作系统提供,每个进程看到的地址是虚拟的,通过页表映射到物理内存。虚拟地址空间的意义在于保护内存、统一管理代码和数据,并解耦进程管理和内存管理。它包括代码段、数据段、堆、栈和环境变量/命令行参数等区域。操作系统通过权限管理确保内存访问合法性。虚拟地址和物理地址的转换由操作系统负责。
摘要由CSDN通过智能技术生成

我们使用编译器所看到的内存地址,全部都是操作系统提供的虚拟地址!

例如:

  int num=0;
  cout<<&num<<endl;

这时输出的内容就是虚拟地址

再如:
在这里插入图片描述
(Linux下程序运行结果如下,其他环境可能有差别)
在这里插入图片描述
解释:

这个程序有一个全局的变量 g_val=0

fork创建子进程之后,子进程中修改了g_val=100

父进程之后读取g_val的值还是0,而且父子进程输出g_val的地址是一样的

一个物理地址的内容是不可能是两个值,我们编译器看到的地址是虚拟地址。

每个进程都有用户级页表,根据映射找到物理地址,所以虚拟地址可以一样。操作系统负责将 虚拟地址 转化成 物理地址 。物理地址,用户一概看不到,由操作系统统一管理。

进程地址空间存在的意义:

  1. 可以保护物理内存,Linux中进程控制块的数据结构是task_struct,task_struct里面又有mm_struct结构,mm_struct里存有标定虚拟地址空间各区域开始和结束的值。通过mm_struct里标定的各区域范围以及页表的权限管理可以判断访问内存操作是否是合法的。
  2. **让每个进程以同样的方式看待代码和数据。**可执行程序本身就划分成了不同的区域,在物理内存中也不是连续的,但是通过虚拟地址空间的映射可以很好地管理可执行程序的不同区域,代码或数据在逻辑上也是连续的。
  3. 将内存管理和进程管理解耦创建进程的同时要分配内存,进程退出要释放内存,如果没有虚拟地址空间,进程管理和内存管理都直接在物理内存上进行,虚拟地址空间可以将进程管理和内存管理解耦,通过虚拟地址空间可以很好的管理各个进程,而内存管理只需要知道某块物理内存是否有效,然后通过虚拟地址和物理地址的映射来访问物理地址即可。

进程虚拟空间:

在这里插入图片描述
各个数据节存放的数据类型介绍如下:

(1) 代码段(.text): 也称文本段,由编译器产生,存放程序的二进制机器码和只读数据,比如程序的可执行指令。.text 段是只读的,且大小在运行时是固定的。任何尝试向.text段写入信息的都会导致段错误。

(2) 数据段: 用于存储全局变量等。其主要包括:

①已初始化的数据段(.data): 存放全局和静态的已初始化变量。本节占用的内存大小在运行时也是固定的,标记为只读。

②末初始化的数据段(.bss): 存放全局和静态的未初始化变量。本节占用的内存大小运行时也是固定的。该段应标记为可读可写,但不可执行。

(3)堆(heap): 用来存储程序运行时动态分配的变量。堆内存的分配释放一般由程序控制,其分配由 new(),malloc() 等实时内存分配函数实现。如果程序没有释放该部分内存,则在程序结束后由系统回收。

(4)栈stack):用来存储函数调用信息和临时变量的数据结构,程序运行时根据需要分配,在不需要时自动清除。

(5)环境变量/命令行参数: 用于存储进程运行时可能用到的系统变量的副本。例如,运行时进程可访问的路径、shell 名称等。该节是可读可写的。除此之外,命令行参数也存储在该区域。

在默认情况下Windows系统将高地址的2 GB空间分配给操作系统(也可配置1 GB),而Linux系统将高地址的1 GB空间分配给内核。这些分配给内核的空间叫内核空间,用户不可访问,用户使用剩下的空间称为用户空间。

文章开始部分的程序,g_val是已初始化的全局变量,存在 .data 部分
虚拟的进程地址通过页表映射到了物理内存的不同地方
在这里插入图片描述

(本文虚拟地址部分摘自 《网络安全》张立江)

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南无故人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值