进程地址空间

&变量 得到的是真实的物理地址吗

下图中为什么地址一样,值不一样:

推断:

该地址,绝对不是物理地址,而是虚拟地址(线性地址)

因为如果物理地址相同,值不可能不一样

综上, &变量 得到的不是真实的物理地址,&变量得到的只是页表上与真实地址空间映射的值, 我们无法得知真实物理地址。

操作系统如何管理空间分配

先描述,再组织(mm_struct)

让每一个进程都认为自己是独占系统物理内存大小,进程彼此之间不知道,不关心对方存在,从而实现一定程度隔离

所谓进程虚拟地址空间,本质是内核的数据结构对象struct mm_struct(类似PCB),mm_struct是task_struct成员

mm_struct规定了task_struct的total-mm,stack_mm,global_mm等起始位置

页表将mm_struct中地址与真实物理地址对应

mm_struct+页表=linux虚拟内存管理方案

创建子进程时的mm_struct & 写时拷贝

子进程的mm_struct以父进程为模板

页表的虚拟地址部分与父进程完全一样,默认映射关系也一样(对应真实物理空间也一样),当父子进程都不对变量进行改变,映射关系依然不变。当父子进程任意一方要改变变量时,OS改变子进程的映射关系(虚拟地址不变,映射的实际地址改变),父进程映射关系不变。

这就是OS写时拷贝,只有写时才会重构子进程的虚拟地址和真实地址的映射关系,为子进程分配新空间

回到开始问题,当要修改gval变量时,OS启动写时拷贝,为子进程分配新空间,改变虚拟地址与真实空间映射。但虚拟地址不变。所以此时父子进程虚拟地址相同,但实际指向不同空间,所以改变自己的值也不会互相影响了

这保证了进程间的独立性,数据独立

变量名本质就是地址

进程=内核数据结构(task_struct &   mm_struct)+自己的代码和数据

理解地址空间

地址本质就是一个数字,可以被保存在unsigned long中

空间区域划分

本质:只要有start & end即可


页表

页表是什么
可以理解为数据结构
类似unordered map

页表中有rwx & isexist

rwx 权限


页表中地址有权限信息(rwx)

char* str ="hello world"
*str ='H'
编译器不会报错
因为编译器无法识别,只有OS运行时才能检查
需要const可向编译器解释str只读特性
这就是为什么要有const,类似的,强制类型转换等也是这个道理

isexist


标记目标文件是否再内存中

支持分批加载/挂起等操作
支持延时开辟空间(不一定申请后立即使用,只要使用时开辟即可)


mm_struct初始化

程序在编译时,各个区域的大小信息已经有了
所以mm_struct可以方便初始化

OS可以根据exe中信息初始化进程信息

我们在程序中malloc等申请堆空间,其实只是虚拟内存中的堆区范围扩大(start&end),其实并没有真正开辟物理内存。可大大提高物理内存使用率(即开辟及用)

(虚拟)进程地址空间的作用

  • 虚拟地址空间&页表:可以保护内存(防止野指针),可以驳回野指针
  • 进程管理 和 内存管理 在系统层面进行解耦合。在初始化进程时可不申请内存
  • 让进程以统一视角看待物理内存

物理内存&虚拟内存的rwx&分区

物理内存中不存在rwx概念,无权限概念, 只是经过页表控制产生了权限

数据可以被加载到物理内存任意位置处, 无分区概念

但经过页表映射后会产生栈区 堆区 代码区 (无序变有序), 会产生权限概念, 分区概念, 方便统一管理/组织

tips


所有内容都是OS自动完成
只要把进程管理好,地址空间就管理好了(task_struct包含mm_struct)
全局变量 字符常量 ---具有全局性,在程序运行期间都会有效

板书笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值