『 Linux 』使用fork函数创建进程与进程状态的查看中提到了对挂起状态的一个理解;
? 挂起状态相比于其他状态来说,挂起状态与CPU并没有太直接的关系;在计算机的磁盘当中,存在着一个swap
分区,这个分区就是为了当内存不足时使进程状态转化为挂起状态而准备的;
? 在队列当中的进程不仅仅是PCB结构体,由于各个进程要通过使用资源来操作自身的代码及数据可以得知一个进程中除了PCB结构体以外还包含着对应的代码以及数据;而挂起状态即为:
? 当内存严重吃紧时,操作系统会将这个进程所对应的代码及数据交换至磁盘中的swap
分区从而到达减轻内存的负担,当这个进程对应的代码及数据被交换至swap
分区时这个进程即为挂起状态;
从『 Linux 』进程地址空间存在的意义 博客中可以知道,加载的本质就是创建进程,在一个进程的创建中,OS在初始化进程地址空间时往往采用延迟加载的策略使得能够更有价值的发挥内存的作用;
所以在一个进程创建之后,OS并不会立马为该进程分配对应的物理内存并在页表中建立映射关系;
当一个进程被创建时只初始化其对应的内核数据结构而并未申请对应物理内存(分配内存建立映射关系)时,这个状态即为新建状态;
这个状态下内核数据结构已经被初始化完毕;
当内存管理单元(MMU)对进程的页表的映射中未找到对应的映射关系,内存管理单元将会向OS反馈这个异常状态,这个异常状态就是 “缺页中断”;
当OS获取到缺页中断的异常状态时将会去把磁盘中的代码和数据加载进内存当中;
在前言中提到对于挂起状态的概念性理解,而在实际上挂起状态不能完全理解为一个进程的当前状态,更能理解为一个进程中的部分代码和数据的状态;
举一个例子:
内存作为计算机中的断电易失存储介质其有着读写速度快的优点,其根据计算机的配置不同有着不同的大小(4GB,8GB…);
而某些游戏的大小少则几十GB,大则上百GB,所以将这个程序中的所有的代码和数据加载同时加载进内存当中是不可能的,所以计算机在处理这些大型程序时将以延迟加载的策略,但本质上进程内所对应的内核数据结构已经被创建;
当内存管理单元(MMU)检查到页表中的虚拟地址不存在对应的映射关系将产生缺页中断的异常状态并通知OS分配内存加载数据,以这种延迟加载的策略使得内存能够更加高效的被利用;
但本质上为了内存的高效利用仅仅只是利用延迟加载方式以分批加载的策略并不能完美的使内存被高效利用;
当进程中部分的代码和数据被执行完毕后将持续保存在内存当中一段时间,这种策略叫做页面缓存(page caching)
;
在页面缓存中,OS会将最近使用过的页面
(包括代码和数据) 保留在内存当中一定时间,以便在将来可能需要再次访问这些内容时能够更快的获取,以提高进程整体的效率;
而当进程间的一些页面长时间未被进程访问使用,或者是在内存吃紧的情况下,OS将会把这些不常用的页面(包括代码和数据)移动至磁盘的swap
分区当中以便释放内存使内存能够有效利用;
这种将页面移至磁盘swap
分区的行为称为唤出
;
而这些被存放进磁盘中swap
分区数据的这种状态被称为挂起状态
;
所以挂起状态不能完全称之为一个进程的状态,当进程仍在调度队列运行时,其某些页面可能已经进行了唤出并发生了页面置换
,也就成为了概念中的挂起状态;
当进程中已经执行了代码和数据或者是并不常用的页面(包括数据和代码)被唤出至swap
当中时,OS将会重新在页表中对这个唤出的页面进行重新建立新的映射关系,这个映射关系将从物理内存地址移至磁盘中的swap
分区,这种行为被称作页面置换
;
需要注意,在新建状态中,对于数据的"内存分配调度"
是取决于内存管理单元(MMU)对是否存在有效页表映射关系的检查所反馈的异常状态(缺页中断),并不会像此处一样建立对应的映射关系;
当然,当磁盘中的swap
分区占满时,OS通常会选择释放swap
分区中的部分数据,以腾出一定的空间来满足系统的内存需求,这个过程通常被称为"交换调度"
;
当系统中所有可用的存储空间(包括物理内存与swap分区)都已被占满时,OS才可能会因为内存不足而报错,导致系统无法正常运行;
在这里应该进行区分一下,当内存管理单元(MMU)对页表的映射关系进行检查时若是未找到对应的映射关系时将会向OS发送异常状态(缺页中断),OS根据对应的异常状态对进程进行对应处理;
这里的概念是对于上文中提到新建状态以及对进程进行的延迟加载所对应的策略方法,这种方法被称为"内存分配"
或是"内存分配调度"
;
本质上与唤入(page in) 唤出(page out)
并没有关系,唤入唤出指的是对于不常用的页面加载进磁盘中的swap
分区与当这个数据重新要被使用时从swap
分区再次加载进内存的概念;
二者不能相提并论;
从上文中可以总结出,实际上进程可以看作一个静态的容器;
它的作用本质上只是表示了一个程序在执行过程中的状态和资源集合(包括代码,数据,寄存器状态等);
本质上进程并不具备行为;
概念上理解的进程的行为本质上是由OS
和其他硬件
来共同完成的;
OS负责管理进程的创建调度销毁,以及资源分配等;
硬件包括中央处理器(CPU)
,进程管理单元(MMU)
和其他设备
等;
从上文可以得出结论,实际上操作系统与内存管理单元之间的关系是互相协作的;
操作系统负责管理系统资源,包括内存管理;一般用来分配内存,管理进程和线程的地址空间,或是调度内存中的页面;
而内存管理单元一般负责将页表中的虚拟地址转化为物理地址并在需要的时候执行内存访问权限的检查,同时检查页表中是否存在有效的映射关系 触发"页面中断" 使得操作系统能够以"延迟加载"
的策略高效使用内存;
操作系统和内存管理单元的共同协作实现了对内存的有效管理和保护;