1.有趣的现象
fork之后代码共享,那存放数据的地址会是一样的吗?
我们用代码来验证一下
这里我们发现了一个问题,同一个变量,内容不一样但是地址是一样的。
结论:
- 父子进程输出的变量不是同一个
- 这个地址不是物理地址,在linux中这种地址叫做虚拟地址(线性地址)
我们在c/c++中的地址都是虚拟地址,而物理地址是操作系统来统一管理的!
2.进程地址空间
这个图片我们都见过;
进程地址空间,每一个进程,都会存在一个进程地址空间,32 [0,4GB]
进程地址空间是数据结构,具体到进程中,就是特定数据结构的对象!
我们的地址空间不具备对我们的代码和数据保存的能力,保存代码和数据是放在物理内存中
将地址空间上的地址(虚拟地址)转化到物理内存中这就是页表的映射
这个进程地址空间,就是OS给我们提供的虚拟地址,当然他不能具备保存数据和代码,那么如何让虚拟地址和物理地址之间建立联系,这就需要页表了,
页表的优点:
- 让物理内存从无序变成有序,让进程以统一的视角,看待内存
- 将进程管理和内存进行解耦合
- 地址空间+页表是保护内存安全的重要手段
补充:内存申请
好处:充分保证内存的利用率,不会空转
提升new和malloc的速度
当我们在内存中申请空间时,不是直接给我们物理内存,而是在地址空间中开辟资源,当我们尝试写入资源时,操作系统会进行缺页中断,给我们建立和物理内存映射关系。