前文可在专栏寻找进程基础
https://blog.youkuaiyun.com/Iiverson2000/article/details/119394135
二谈虚拟地址
虚拟地址究竟是什么?
举个例子:
一个课桌,我需要画三八线,那么就需要对桌子进程刻度分化,比如 0-50 和50-100 分别为各自的地盘。
而此时 这里的 0 - 100 刻度 就是 我们所谓的虚拟地址,而真正的物理地址就是指桌子这个客观大小
进程地址空间本质:内存中的一种内核数据结构 : mm_struct
我们知道在32位系统中,以字节为单位,有2^32 个空间 ,这是一个进程能访问的最大地址空间
而我们的OS就开始给每一个进程画大饼。
OS说:你们每个进程都有4个G的空间,我把能给的都给你们,像一个慈祥的老父亲。
然后OS用一把尺子,将这些空间划分为各个区域,就是我们的进程地址空间
那究竟是如何划分的呢?其实很简单 ,在mm_struct中用无符号整形变量 标定了 每个区域的起始和终止。
其中每一个虚拟的区域中的刻度,就叫做虚拟地址 --也称为线性地址。

所以,当我们需要给堆和栈进行增容时,仅仅是改变 他们分别的 start 和 end 的大小,再通过页表进行映射。
还有一个小细节,我们都知道可执行程序存在于硬盘中,其实在编译器对源文件进行编译的时候,就自动将文件分为多个区域,.code .readonly .init . uninit 这些区域。当代码被加载到内存中时,进程虚拟地址通过页表映射关系找到这些区域是很对应的。 这就是编译器在操作系统级别的工作。
什么叫做创建进程
对于linux , 简单的理解创建进程就是 : struct task_struct + struct mm_struct + 页表 的先描述后组织。(当然还有很多内容,我们后续在进行补充)
虚拟地址的优势
- 有了虚拟地址,永远不会发生系统界别的内存越界。我们回忆一下,当我们写c++代码发生的越界行为,其实仅仅是处于虚拟地址中的越界,仅仅影响的是自身进程 是否正确,并不会影响到系统其他进程。
当我们栈中有一个指针指向一个空间,想要对其进行访问写入时,需要先通过页表的检查,若没有这个空间则此进程会在虚拟空间中直接被kill掉
虚拟空间+页表 == 内存保护 - 我们上文提到,每一个进程都被OS分配的4个G 的空间,那事实是整个内存一共才4G (32位),那这样会发生每个进程过度开辟 ,导致物理内存不够的情况吗? 答案是不会。
我们一个进程在运行时,操作系统不会直接一次性将其开辟完,比如我们玩的游戏甚至有上百G,操作系统在进行调度的时候,会根据物理内存的具体情况,以及各种进程调度算法,对其进行相应内存开辟。简单来说就是,用到某一个部分再去开辟。
这种做法的优势就是:保证了进程之间的独立性 和 空间的合理分配 —进程调度 和 内存管理进行解耦或者分离

本文深入探讨了虚拟地址的概念及其在操作系统中的应用。通过生动的例子解释了虚拟地址如何帮助实现进程间的内存隔离,并介绍了进程创建的过程及虚拟地址带来的优势。
2019

被折叠的 条评论
为什么被折叠?



