Skip to content

Commit

Permalink
feat: add Operating Systems Storage Management
Browse files Browse the repository at this point in the history
  • Loading branch information
RealBeBetter committed Dec 16, 2022
1 parent b47b8b1 commit 27664bc
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 1 deletion.
63 changes: 62 additions & 1 deletion Operating Systems.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,67 @@ IO多路复用(IO Multiplexing)是指单个进程/线程就可以同时处
- 利用杀死进程:强制杀死某些进程直到死锁解除为止,可以按照优先级进行。
</details>
### 分页和分段有什么区别?
### 存储管理方式
内存管理方式分为**连续分配管理**和**非连续分配管理**。连续分配管理分为单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配四种;非连续分配管理又叫离散分配方式,如果离散分配的基本单位是页Page,则称为分页存储管理方式;如果离散分配的基本单位是段Segment,则称为分段存储管理方式。
**连续分配管理方式**允许一个用户程序分配一个连续的内存空间。
- 单一连续分配:多用于单用户单任务的操作系统中,是一种简单的存储管理方式。单一连续分配中,会将存储空间分配为**系统区**和**用户区**。系统区存放系统进程,用户区存放用户进程,这样的管理可以避免用户进程影响到系统进程。这种分配方式中,比如0-a的地址空间存放系统区,那么a+1-n的地址空间都存放用户区。
- 固定分区分配:是一种最简单的可运行多道程序的存储管理方式。固定分区分配首先要**划分分区**,之后进行**内存分配**。
- 内存分区分为分区大小相等和分区大小不等两种。分区大小相等的情况下,如果进程大小不相等容易造成内存浪费或者内存不够进程无法运行的问题,所以通常用于进程内存大小相等的情况中。分区大小不相等,就是根据常用的大小(较多的小分区,适量的中分区,少量的大分区)进行分区,这样就可以更好地利用内存空间,但是这样的方式需要维护一个分区使用表。
- 内存分配要维护一张分区使用表,通常按照进程大小进行排序。每次在进行内存分配的时候,要查看哪些分区能够容纳该进程。
![image-20220527171132306](_v_images/202205271711368.png)
- 动态分区分配:根据进程的需要,动态地分配内存空间。这样的分配方式涉及到分区中的数据结构、分区分配算法以及分区的分配和回收操作三个问题。
- 分区分配中的数据结构主要分为空闲分区表和空闲分区链两种。空闲分区表维护空闲分区的序号、空闲分区的起始地址以及空闲分区的大小数据。空闲分区链相当于一个双向链表,维护空闲分区;为了方便检索在分区尾部设置一个分区的状态位以及分区大小。
- 分区分配算法主要有五种方法。**首次适应算法(First Fit)**,利用空闲分区链实现,将空闲分区按照地址递增(注意与后面的最佳适应区分,这里按照的是地址递增)进行排序,然后根据进程的大小**从链首查找空闲分区链**,第一个能够适应的就分配。**循环首次适应算法(Next Fit)**,不是每次都从链首开始查找,而是从上一次找到的空闲分区的下一个空闲分区开始查找,直到查找到一个能够使用的分区,之后动态地分配内存(会导致后续大空闲分区变少)。**最佳适应算法(Best Fit)**,将空闲分区链按照大小进行排序,找到第一个适应的空闲分区即可(最大限度利用空闲分区)。**最坏适应算法(Worst Fit)**,与最佳适应相反,排序之后每次挑选最大的分区使用,对中小作业有利,不易产生碎片。**快速适应算法(Quick Fit)**,根据大小将空闲分区进行分类,维护多个空闲分区链;这样的好处是可以加快检索,相比一条链能够更快地检索目标进程。
- 分区分配和回收:主要操作是内存的分配和内存的回收。内存分配中,若空闲分区内存大小-用户进程内存大小<=预设不可切分内存大小,则进行一次内存的分配;否则将剩余的内存空间放到空闲内存链中,继续下次的使用。内存回收,主要看是否和空闲分区相邻,如果相邻就直接合并;否则就建立新的表项,维护回收区的内存起始地址和大小。
- 动态重定位分区分配:在连续分配方式中,必须把系统进程或者用户进程装入一个连续的内存空间中。这个时候可能会因为程序的大小与分区的大小不一致的问题产生内存碎片。这个时候我们要想插入新的进程,即使碎片空间总和支持进程,也无法再分配空间,所以我们要把内存空间进行一个整理。
![image-20220527171146904](_v_images/202205271711967.png)
- 整理内存地址,是将程序的内存地址整理成在物理上相邻的状态。程序使用的地址在分区装载之后仍然是相对地址,要想将相对地址转换为相邻物理地址,必然会影响到程序的执行。为了不影响程序的执行,需要在硬件上提供对程序的内存地址转换支持,于是引入重定位寄存器,用它来存放程序在内存中的起始地址。
![image-20220527171158815](_v_images/202205271711882.png)
**非连续分配管理方式**允许将一个程序分散地装入不相邻的内存分区。根据内存分区的大小分为分页式存储管理方式和分段式存储管理方式。
- 页存储:页存储首先需要将一个进程的**逻辑内存空间划分为多个内存大小相等的页**,然后将物理内存空间划分为相等的大小个数的物理块Block(页框Frame)。分配的时候将多个页面放入多个不相邻的物理块中。这样的划分之后,通常进程的最后一页存不满,会产生内存碎片——”页内碎片“。
- 页面大小:页面大小的选定需要适当。如果过小,虽然可以减少页内碎片的产生,但是需要更大的页表,而且页面切换更频繁;如果太大就会产生较大的内存碎片。所以大小的选择应该适中,通常为2的整数次幂,范围为512B至8KB。
- 页表:页表主要保存进程占用的页数,同时存储逻辑内存空间页到物理内存块的映射。
![image-20220527171217837](_v_images/202205271712893.png)
- 地址转换:页表要存储地址映射,那么首先得有一个地址变换机构。基本地址变换机构,主要用来建立逻辑地址到物理内存空间地址的映射。传统系统中,主要使用寄存器来存放页表(寄存器速度快,有利于变换地址),那么每一个页表都需要寄存器来存放,成本过高。进程数量过多的情况下,首先将页表的**起始地址和页表长度**存放在PCB中,之后在进程运行的时候再将数据读取到PTR(Page-Table Register,页表寄存器)。读取数据的时候,地址转换机构会将相对地址转换为页号以及页内地址两部分,之后根据页号检索页表。检索之前会将页号和页表长度进行比较,如果页号大于或等于页表长度,则说明出现了访问越界,会出现越界中断。
![image-20220527171233940](_v_images/202205271712003.png)
- 具有块表的地址转换机构:页表存放在内存中,那么将要先查页表,计算得出物理地址之后访问物理地址,是两次检索过程。
- > 为了提高地址变换速度,可在地址变换机构中增设一个具有并行查寻能力的特殊高速 缓冲寄存器,又称为“联想寄存器”(Associative Memory),或称为“快表”。
对于32位操作系统,使用两级页表结构式合适的;但是对于64位操作系统,建议采用多级页表。
- 段存储:使用段存储而不再使用页存储,第一个原因是提高内存的利用率,第二个原因是满足开发者在编程中的多种需求。主要是满足编程中的几个新的需求:**方便编程(简化逻辑地址访问方式)、信息共享(段式信息的逻辑单位)、信息保护(对信息的逻辑单位实现保护)、动态增长(分段更加满足动态增长的需求)、动态链接(链接装载使用段更符合需求)**。
- 分段:作业的地址空间被划分为若干个段,每个段定义了一组逻辑信息。
- 段表:为每个分段分配一个连续的分区,进程每个段可以离散地存放到不同分区中,所以也需要维护一张段表,使得进程能够查到逻辑地址对应的物理地址,这个表就是段映射表,简称段表。
- 地址变换机构:为了实现逻辑地址到物理地址的映射,系统设置了一个段表寄存器,用于存放段表地址和段表长度,如果段号大于段表长度,则表示发生了越界访问,产生越界中断;若未越界,找出该段对应段表项的位置,读出内存中的起始地址;再检查段内地址是否超过段长,如果超过段长,发出越界中断;否则将基址与段内地址相加,得出内存的物理地址。
- 分段和分页的主要区别:①页是信息的物理单位,段是信息的逻辑单位;②页的大小由系统决定,段的大小不固定;③分页作业地址空间是一维的,分段作业地址空间则是二维的。即页的地址空间可以用一个符号来标识,而段的地址空间不仅要知道段名还要知道段内地址。
- 段页存储:分页存储能提高内存利用率,分段存储能满足用户的更多需求。为了各取所长,产生了段页存储的管理方式。
- 基本原理:段页存储,就是既分段也分页,先分段再分页。地址结构由段号、段内页号、页内地址三部分组成。
- 地址变换过程:首先也需要准备一个段表寄存器,存放段表起始地址和段表长。首先将段号和段表长相比较是否越界;再利用段表起始地址和段表号来找到段表项在段表中的位置,从而得到页表地址;再之后使用段内页号来获取页表项的位置,找出物理块号,用物理块号和页内地址来构成物理地址。
#### 分页和分段有什么区别?
- 页式存储:用户空间划分为大小相等的部分称为页(page),内存空间划分为同样大小的区域称为页框,分配时以页为单位,按进程需要的页数分配,逻辑上相邻的页物理上不一定相邻;
- 段式存储:用户进程地址空间按照自身逻辑关系划分为若干个段(segment)(如代码段,数据段,堆栈段),内存空间被动态划分为长度不同的区域,分配时以段为单位,每段在内存中占据连续空间,各段可以不相邻;
- 段页式存储:用户进程先按段划分,段内再按页划分,内存划分和分配按页。
Expand Down Expand Up @@ -576,6 +636,7 @@ C 语言使用运行时栈来存储过程信息。每个函数的信息存储在
### 参考
- [进程间通信IPC -- 简书](https://www.jianshu.com/p/c1015f5ffa74)
- [【面试】计算机操作系统-CSDN博客](https://blog.csdn.net/qq_43103529/article/details/121022006)
- [面试/笔试第二弹 —— 操作系统面试问题集锦 - CSDN博客](https://blog.csdn.net/justloveyou_/article/details/78304294)
- [线程同步与并发 - - SegmentFault](https://segmentfault.com/a/1190000018970361)
- [彻底搞懂epoll高效运行的原理](http://baijiahao.baidu.com/s?id=1641172494287388070&wfr=spider&for=pc)
Expand Down
Binary file added _v_images/202205271711368.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _v_images/202205271711882.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _v_images/202205271711967.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _v_images/202205271712003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _v_images/202205271712893.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 27664bc

Please sign in to comment.