程序地址空间
它不是内存,它是虚拟地址空间。
虚拟地址空间
我们先见见它的特点:
刚开始父进程pid是5294,子进程pid是5295,对应的value和value地址刚开始打都是100,但是当我们子进程对全局变量进行了修改,子进程变量是300,父进程变量是100,地址却是一样的。原因是物理地址不同。
多进程在读取同一个地址的时候,怎么可能出现不同的结果?
地址没变 -> 这里的地址绝对不是物理地址 -> 曾经我们学习的语言级别的地址(指针),不是对应的物理地址 -> 虚拟地址(线性地址)【逻辑地址】
解释:
感性理解虚拟地址空间:
a.进程它会认为自己是独占系统资源的(事实上并不是)
说白了进程地址空间就是操作系统给进程画的大饼。
在软件层面,如何“画饼”呢??画饼的本质就是在大脑中构建一个蓝图 — 数据结构对象 。
操作系统有500个进程 ,给每个进程创建虚拟地址空间,进程要被管理,虚拟地址空间也要被管理。
如何管理?先描述在组织。
地址空间本质:是内核的一种数据结构 mm_struct
地址空间有很多区域,那么它是内核数据结构,它的成员有哪些?
区域划分:区域调整
32位的数据 -> unsigned int (32bits)
当我们创建一个进程,操作系统给这个进程malloc一个task_struct内核数据结构。接着操作系统结合地址空间创建了一个mm变量。
heap && stack
所谓区域调整,本质就是修改各个区域的start
or start
。
我们在C/C++种,定义局部变量,malloc new堆空间就是扩大栈区域或者堆区。在函数调用完毕或者free空间的时候就是缩小堆区或者栈区。
进程地址空间和物理内存之间映射关系
上面所有操作都是由操作系统帮我们做的。
进程1进程2是两个不同的进程,两者在物理内存中有各自的代码和数据,进程1 进程2看不到物理内存,只能通过自己的地址空间访问。
理解进程地址空间
为什么存在进程地址空间?
1.如果让进程直接访问物理内存,进程可能会越界非法操作。但是虚拟地址空间可以变相的保护,当进程在非法访问时页表就拦截了。因为有页表的存在,所有的进程都会映射到合法的内存中。
2.地址空间的存在,可以更方便的进行进程和进程的数据代码的解耦,保证了进程独立这样的特性。
如下如,两个进程和其进程地址空间,中间是物理内存。
修改过程和左右两侧虚拟地址没有关系,所以上层在用的时候用的是虚拟地址,底层经过页表被映射到内存中不同的区域,此时我们看到的现象是大家的地址一样但内容不一样。
写时拷贝:当写入的时候就重新拷贝一份,这个工作是操作系统自动做的。
操作系统通过地址空间,通过页表,让不同的进程,映射到不同的物理内存处。
3.让进程以统一的视角,来看待进程对应的代码和数据等各个区域,方便使用编译器也以统一的视角来进行编译代码,编完即可立即直接使用。
重新再理解一次地址空间:
进程的task_struct由指针指向内核当中的数据结构指向mm_struct,经过地址空间经过页表映射到物理内存。
假设磁盘有一个我们写的程序,名字叫my.exe,编好了代码对应的可执行程序,在没有被加载到内存的时候我们的可执行程序里面早就有地址(程序内部使用的地址)了,这个地址叫做逻辑地址。编译器也要遵守OS对应的规则。编译器编译我们的代码的时候,就是按照虚拟地址空间的方式进行对我们代码和数据的编址(32位),也就是说代码数据在磁盘上早就划分好了。当程序被加载到物理内存中的时候,天然拥有一个外部的物理地址。
可执行程序里两个方法 fun(use a;)地址是0x1234, main(){fun()}地址是0x1122,main函数内部调用了一个函数叫作fun(),在磁盘中还有一个全局变量 a = 10,它对应的地址是0x2222,这些地址是代码在编译期就有了所对应的逻辑地址。把磁盘上的代码数据加载到物理内存,数据自己本身就有地址fun函数用a的时候就能自己找到他,虚拟地址空间有代码段、未初始化、初始化,所以代码在物理内存中被加载,同时也就具备了物理地址。所以我们现在有两套地址,一套是标识物理内存中代码和数据的地址,另一套是在程序内部互相跳转的时候的虚拟地址。我们读取物理内存中的地址,eg读取main的物理地址。CPU从main函数开始跑,加载的是main函数的虚拟地址,此时查页表访问到物理地址,就调main函数,开始一步一步往后执行,我们要调fun函数,那么就是把fun函数对应的虚拟地址(CPU读的是指令,指令内部就有地址(虚拟地址))load到CPU中,读到0x1234,然后就通过页表映射开始调fun函数,fun函数要用a,那么我们就把use a的指令读取到CPU中,然后CPU读到a的地址0x2222,要进行的操作是++操作,然后通过地址空间找页表,然后映射到物理内存,找到全局变量a。在整个过程CPU压根没有见到物理地址。