江宁滨江网站建设,建商城网站带app多少钱,大连做网站需要多少钱,网络管理系统正常运行的前提必须是文章目录#x1f3aa; 进程地址空间#x1f680;1.写时拷贝与虚拟地址#x1f680;2.地址空间引入#x1f680;3.地址空间的意义⭐3.1 虚拟地址寻址⭐3.2 虚拟地址意义#x1f3aa; 进程地址空间
地址空间#xff08;address space#xff09;表示任何一个计算机实体所… 文章目录 进程地址空间1.写时拷贝与虚拟地址2.地址空间引入3.地址空间的意义⭐3.1 虚拟地址寻址⭐3.2 虚拟地址意义进程地址空间
地址空间address space表示任何一个计算机实体所占用的内存大小。比如外设、文件、服务器或者一个网络计算机。地址空间包括物理空间以及虚拟空间。在32位平台下程序地址空间大小是2^32也就是4GB. 补充 命令set / unset 功能查看环境变量 / 取消用户环境变量 set可以显示当前用户环境变量(通常比env显示的更详细)unset可以取消用户自己设置的本地变量和环境变量
1.写时拷贝与虚拟地址
先来看一段测试代码
test.c:
#include stdio.h
#include assert.h
#include unistd.hint g_value 100; //全局变量int main()
{pid_t id fork();assert(id 0);if(id 0){//childwhile(1){printf(我是子进程, 我的id是: %d, 我的父进程是: %d, g_value: %d, g_value : %p\n,\getpid(), getppid(), g_value, g_value);sleep(1);g_value200; // 只有子进程会进行修改}}else{//fatherwhile(1){printf(我是父进程, 我的id是: %d, 我的父进程是: %d, g_value: %d, g_value : %p\n,\getpid(), getppid(), g_value, g_value);sleep(1);}}
}可以看到对于全局变量g_value父子进程的地址相同即使子进程改变了g_value的值父进程的该变量值依然没变而且地址也跟子进程一样所以说该地址是物理地址吗如果是那么怎么可能对于同一个地址读取到不同的数值显然我们语言级别上打印出来的地址绝对不是物理地址而是——虚拟地址关于写时拷贝和虚拟地址已经讲过——进程描述与进程状态.
2.地址空间引入
假如有一个大富翁他总共有10亿的资产他一共有四个私生子他对每个私生子说以后等他老了就把这10亿的资产送给他可实际上这真能实现吗这其实也是我们所说的画饼每个私生子并不知道其它人的存在每个人都以为自己将来能继承10亿的资产。 实际上操作系统也是如此操作系统也就是大富翁而内存就是它拥有的资产而私生子就是进程在每个进程的视角看来它们都是独自享有所有的内存可实际上这是操作系统为它们画的饼而这个饼也就是进程地址空间也被称为虚拟地址、线性地址在Linux下叫struct mm_struct
那么上图中的堆区栈区代码区数据区该如何理解呢每个进程分的地址空间实际上就是对线性地址空间的划分即
struct area{int start;int end;
}即对线性地址空间的划分也就是对结构体内start和end的修改栈区的向下调整和堆区的扩大即修改对应的边界值
3.地址空间的意义
地址空间相当于一层媒介它的本质实际上也是软件层操作系统先通过虚拟地址找到物理地址。
⭐3.1 虚拟地址寻址
虚拟地址最终会转换为物理地址那么是怎么转换的呢 这样便对我们上面的例子有了解释子进程在修改g_value的值的时候操作系统会写时拷贝即将该变量拷贝到一块新的物理地址上但是虚拟地址并没有发生变化而寻址的过程是OS通过虚拟地址查找页表和MMU(内存管理单元),通过其映射到两块不同的物理地址块上
而fork()函数的双返回值问题也就有了答案返回的本质就是写入谁先返回OS就让谁通过虚拟地址发生写时拷贝
⭐3.2 虚拟地址意义
为什么要有地址空间呢原因有以下三点
1. 防止地址随意访问保护物理内存与其他进程
试想如果没有地址空间那么进程的PCB指针就会随意的访问内存如果因为人工代码失误造成野指针问题恰好访问了另一个进程的物理内存修改了下一个进程的数据那么就可能导致该进程故障安全性较低.
而有了虚拟地址即使恶意访问页表在寻址的时候也会匹配该物理块是否能被该用户访问如果不能页表将会终止访问这时我们的编译器控制台就会提示野指针越界所以虚拟地址的引入提高了安全性.
2. 将进程管理与内存管理进行解耦合
我们先思考一个问题当向系统申请空间的时候OS是立即分配给你还是需要的时候再给你
OS一般不允许任何的浪费或者不高效进程在申请内存后不一定立马使用在申请成功后如果这个进程不立即使用那么是不是在这一段时间内就会有一小段物理块处于闲置状态(自己不用其它进程也不能用)
如果不止一个进程这样成千上万个进程都这样是不是就会造成大量内存空间的浪费所以当我们使用malloc分配空间的时候OS一般不会立即分配给你而是在虚拟地址上分配一块空间但实际上这块空间并没有映射到物理地址上而是在使用的时候页表才会映射到物理内存上分配空间。这就实现了进程管理和内存的管理的解耦合
3. 可以让进程以统一的视角看待自己的数据和代码
程序在被编译的时候没有被加载到内存我们程序内部也是有地址的这个地址也是虚拟地址源代码在被编译的时候就是按照虚拟地址空间的方式进行对代码和数据早就已经编好了对应的编址.OS通过虚拟地址寻址找到代码和数据存放的物理地址在进程的视角看来自己都享有整个内存空间视角相同进程的代码和数据必须一直在内存吗可以边加载边执行因为有虚拟地址的空间的存在需要加载到内存时缺页中断换出内存