秋招操作系统重点知识汇总

操作系统基础

秋招八股文准备阶段信息汇总,主要信息来源于:
简略重要信息:JavaGuide
详细信息:小林Coding

什么是操作系统?

操作系统是管理计算机硬件和软件资源的程序,是计算机的基石。

操作系统本质上是运行在计算机上的软件程序,用于管理计算机硬件和软件资源。举例:运行在你电脑上的所有应用程序都通过操作系统来调用系统内存以及磁盘等等硬件。

操作系统存在屏蔽了硬件层的复杂性。操作系统就像硬件使用的负责人,统筹着各种相关事项。

操作系统的内核是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。

在这里插入图片描述

什么是系统调用?

根据进程访问资源的特点,我们可以把进程在系统上的运行分为两个级别:

1.用户态:用户态运行的进程可以直接读取用户程序的数据

2.系统态:可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制

那么什么是系统调用呢?

我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能,就需要系统调用了

也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理,进程控制,内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。

这些系统调用按功能可以分为如下几类:

设备管理:完成设备的请求或释放,以及设备启动等功能

文件管理:完成文件的读,写,创建以及删除等功能

进程管理:完成进程的创建,撤销,阻塞及唤醒等功能

进程通信:完成进程之间的消息传递或信号传递等功能

内存管理:完成内存的分配,回收以及获取作业占用内存区大小及地址等功能

系统调用的过程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eCsNCP2r-1657849354123)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220611140259856.png)]

内核程序执行在内核态,用户程序执行在用户态。当应用程序使用系统调用时,会产生一个中断。发生中断后, CPU 会中断当前在执行的用户程序,转而跳转到中断处理程序,也就是开始执行内核程序。内核处理完后,主动触发中断,把 CPU 执行权限交回给用户程序,回到用户态继续工作。

进程和线程

进程

我们编写的代码只是一个存储在硬盘的静态文件,通过编译后就会生成二进制可执行文件,当我们运行这个可执行文件后,它会被装载到内存中,接着 CPU 会执行程序中的每一条指令,那么这个运行中的程序,就被称为「进程」(Process)

进程的状态

进程有五种状态:创建,就绪,执行,阻塞,终止。一个进程创建后,被放入队列处于就绪状态,等待操作系统调度执行,执行过程中可能切换到阻塞状态(并发),任务完成后,进程销毁终止。

创建状态:一个应用程序从系统上启动,首先进入创建状态,需要PCB块完成资源分配。

就绪状态:在创建状态完成后,进程已经准备好,处于就绪状态,但是还未获得处理器资源,无法运行

运行状态:获取处理器资源,被系统调度,当具有时间片开始进行运行状态。如果进程的时间片用完了就进入就绪状态

阻塞状态:在运行状态期间,如果进行了阻塞的操作,如耗时的I/O操作,此时进程暂时无法操作就进入到了阻塞状态,在这些操作完成后就进入就绪状态。等待再次获取处理器资源,被系统调度,当具有时间片就进入运行状态

终止状态:进程结束或者被系统终止,进入终止状态

在这里插入图片描述

进程的上下文切换

各个进程之间是共享 CPU 资源的,在不同的时候进程之间需要切换,让不同的进程可以在 CPU 执行,那么这个一个进程切换到另一个进程运行,称为进程的上下文切换

进程是由内核管理和调度的,所以进程的切换只能发生在内核态。

所以,进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。

通常,会把交换的信息保存在进程的 PCB,当要运行另外一个进程的时候,我们需要从这个进程的 PCB 取出上下文,然后恢复到 CPU 中,这使得这个进程可以继续执行,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WD573KdE-1657849354124)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220611145249386.png)]

线程

线程是进程当中的一条执行流程。

同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。

线程的优点与缺点

优点:

一个进程中可以有多个线程

各个线程之间可以并发执行

各个线程之间可以共享地址空间和文件等资源

缺点:

当进程中的一个线程崩溃时,会导致其所属进程的所有线程崩溃(这里是针对C/C++语言,java语言中的线程崩溃不会造成进程崩溃)

进程与线程的比较:

进程是资源(包括内存,打开的文件等)分配的单位,线程是CPU调度的单位;

进程拥有一个完成的资源平台,而线程只独享必不可少的资源,如寄存器和栈

线程同样具有就绪,阻塞,执行三种基本状态,同样具有状态间的转换关系;

线程能够减少并发执行的时间和空间开销;

对于,线程相比进程能减少开销,体现在:

线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息,文件管理信息,而线程在创建的时候,不会涉及这些资源管理信息,而是共享它们;

线程的终止时间比进程快,因为线程释放的资源相比进程少很多

同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的

对于同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使线程之间的数据交互效率更高了

线程的上下文切换

这还得看线程是不是属于同一个进程:

  • 当两个线程不是属于同一个进程,则切换的过程就跟进程上下文切换一样;
  • 当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据

所以,线程的上下文切换相比进程,开销要小很多。

线程的实现

主要有三种线程的实现方式:

  • 用户线程:在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理。
  • 内核线程:在内核中实现的线程,是由内核空间的线程
  • 轻量级进程:在内核中来支持用户线程

进程间的通信方式

进程间的通信方式由哪几种:

  • 1.管道/匿名管道:用于具有亲缘关系的父子进程或者兄弟进程之间的通信

  • 2.有名管道:匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先入先出。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。

  • 3.信号:对于异常情况的工作模式,就需要用【信号】的方式通知进程,信号是进程间通信机制中唯一的异步通信机制,因为可以在任何时候发送信号给某一进程,一旦有信号产生,我们就有下面这几种,用户进程对信号的处理方式。

    1.执行默认操作。Linux 对每种信号都规定了默认操作,例如,上面列表中的 SIGTERM 信号,就是终止进程的意思。

    2.捕捉信号。我们可以为信号定义一个信号处理函数。当信号发生时,我们就执行相应的信号处理函数。

    3.忽略信号。当我们不希望处理某些信号的时候,就可以忽略该信号,不做任何处理。有两个信号是应用进程无法捕捉和忽略的,即 SIGKILLSEGSTOP,它们用于在任何时候中断或结束某一进程。

  • 4.消息队列:消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先入先出的原则。与管道不通的是消息队列存放在内核中,只有在内核重启或者显式的删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先入先出的次序读取,也可以按照消息的类型读取,比FIFO更有优势。消息队列克服了信号承载信息量少,管道只是承载无格式字节流以及缓冲区大小受限等缺点。

  • 5.信号量:信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决于同步相关的问题并避免竞争条件。

  • 6.共享内存:使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新,这种方式需要依赖某种同步操作,如互斥锁或信号量。可以说这是最有用的进程间通信方式。

  • 7.套接字:此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。

线程间的同步方式

  • 线程间的同步方式有哪些?

线程同步是两个或多个共享关键资源的线程的并发执行。应该同步线程以避免关键资源使用冲突。操作系统一般有下面三种线程同步的方式:

  • 1.互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问
  • 2.信号量(Semaphore):它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
  • 3.事件(Event):Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作

进程间的调度算法

  • 操作系统中的调度算法有哪些?
  • 1.先到先服务调度算法:从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度

  • 2.短作业优先的调度算法:从就绪队列中选择一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度

  • 3.时间片轮转调度算法:每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。

  • 4.多级反馈队列调度算法:

    • 设置了多个队列,赋予每个队列不同的优先级,每个队列优先级从高到低,同时优先级越高时间片越短
    • 新的进程会被放入到第一级队列的末尾,按先来先服务的原则排队等待被调度,如果在第一级队列规定的时间片没运行完成,则将其转入到第二级队列的末尾,以此类推,直至完成;
    • 当较高优先级的队列为空,才调度较低优先级的队列中的进程运行。如果进程运行时,有新进程进入较高优先级的队列,则停止当前运行的进程并将其移入到原队列末尾,接着让较高优先级的进程运行;

    可以发现,对于短作业可能可以在第一级队列很快被处理完。对于长作业,如果在第一级队列处理不完,可以移入下次队列等待被执行,虽然等待的时间变长了,但是运行时间也会更长了,所以该算法很好的兼顾了长短作业,同时有较好的响应时间。

  • 5.优先级调度: 为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。

死锁

  • 什么是死锁

死锁描述的是这样一种情况:多个进程/线程 同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于进程/线程被无限期地阻塞,因此程序不可能正常终止

  • 产生死锁的四个必要条件
  • 互斥:资源必须处于非共享状态,即一次只有一个进程可以使用。如果另一进程申请该资源,那么必须等待知道该资源被释放为之

  • 占有并等待:一个进程至少应该占有一个资源,并等待另一个资源,而该资源被其他进程所占有

  • 非抢占:资源不能被抢占。只能在持有资源的进程完成任务后,该资源才会被释放

  • 循环等待:有一组等待进程 {P0, P1,..., Pn}P0 等待的资源被 P1 占有,P1 等待的资源被 P2 占有,…,Pn-1 等待的资源被 Pn 占有,Pn 等待的资源被 P0 占有。

    只有四个条件同时成立时,死锁才会出现。

  • 解决死锁的方法

一般情况下,有预防,避免,检测和解除四种

  • 预防是采用某种策略,限制并发进程对资源的请求,使得死锁的必要条件在系统执行的任何时间上都不满足。
  • 避免则是在系统分配资源时,根据资源的使用情况提前做出预测,从而避免死锁的发生
  • 检测是指系统设有专门的机构,当死锁发生时,该机构能够检测死锁的发生,并精确的确定与死锁有关的进程和资源
  • 解除是与检测相配套的一种措施,用于将进程从死锁状态下解脱出来
  • 死锁的预防

一般比较实用的预防死锁的方法,是通过考虑破坏占有并等待循环等待

1.静态分配策略:

静态分配策略可以破坏死锁产生的第二个条件(占有并等待)。所谓静态分配策略,就是指一个进程必须在执行前就申请到它所需要的全部资源,并且知道它所要的资源都得到满足后才开始执行。进程要么占有所有的资源然后开始执行,要么不占有资源,不会出现占有一些资源等待一些资源的情况

静态分配策略逻辑简单,实现也很容易,但这种策略 严重地降低了资源利用率,因为在每个进程所占有的资源中,有些资源是在比较靠后的执行时间里采用的,甚至有些资源是在额外的情况下才是用的,这样就可能造成了一个进程占有了一些 几乎不用的资源而使其他需要该资源的进程产生等待 的情况。

2.层次分配策略:

层次分配策略破坏了产生死锁的第四个条件(循环等待)。在层次分配策略下,所有的资源被分成了多个层次,一个进程得到某一次的一个资源后,它只能再申请较高一层的资源;当一个进程要释放某层的一个资源时,必须先释放所占用的较高层的资源,按这种策略,是不可能出现循环等待链的,因为那样的话,就出现了已经申请了较高层的资源,反而去申请了较低层的资源,不符合层次分配策略

  • 死锁的避免

上面提到的 破坏 死锁产生的四个必要条件之一就可以成功 预防系统发生死锁 ,但是会导致 低效的进程运行资源使用率 。而死锁的避免相反,它的角度是允许系统中同时存在四个必要条件 ,只要掌握并发进程中与每个进程有关的资源动态申请情况,做出 明智和合理的选择 ,仍然可以避免死锁,因为四大条件仅仅是产生死锁的必要条件。

我们将系统的状态分为安全状态和不安全状态,每当在未申请者分配资源前先测试系统状态,若把系统资源分配给申请者会产生死锁,则拒绝分配,否则接受申请,并为它分配资源。

(如果操作系统能够保证所有的进程在有限的时间内得到需要的全部资源,则称系统处于安全状态,否则说系统是不安全的。很显然,系统处于安全状态则不会发生死锁,系统若处于不安全状态则可能发生死锁。)

那么如何保证系统保持在安全状态呢?通过算法,其中最具有代表性的 避免死锁算法 就是 Dijkstra 的银行家算法,银行家算法用一句话表达就是:当一个进程申请使用资源的时候,银行家算法 通过先 试探 分配给该进程资源,然后通过 安全性算法 判断分配后系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待,若能够进入到安全的状态,则就 真的分配资源给该进程

死锁的避免(银行家算法)改善解决了 资源使用率低的问题 ,但是它要不断地检测每个进程对各类资源的占用和申请情况,以及做 安全性检查 ,需要花费较多的时间。

  • 死锁的检测

对资源的分配加以限制可以预防和避免死锁的发生,但是都不利于各进程对系统资源的充分共享。解决死锁的另一条途径是死锁检测和解除 (这里突然联想到了乐观锁和悲观锁,感觉死锁的检测和解除就像是 乐观锁 ,分配资源时不去提前管会不会发生死锁了,等到真的死锁出现了再来解决嘛,而 死锁的预防和避免 更像是悲观锁,总是觉得死锁会出现,所以在分配资源的时候就很谨慎)。

这种方法对于资源的分配不加以限制,也不采取死锁避免措施,但系统定时地运行一个“死锁检测”的程序,判断系统内是否出现死锁,如果检测到死锁,再采取措施去解除它。

死锁检测步骤

知道了死锁检测的原理,我们可以利用下列步骤编写一个 死锁检测 程序,检测系统是否产生了死锁。

  1. 如果进程-资源分配图中无环路,则此时系统没有发生死锁
  2. 如果进程-资源分配图中有环路,且每个资源类仅有一个资源,则系统中已经发生了死锁。
  3. 如果进程-资源分配图中有环路,且涉及到的资源类有多个资源,此时系统未必会发生死锁。如果能在进程-资源分配图中找出一个 既不阻塞又非独立的进程 ,该进程能够在有限的时间内归还占有的资源,也就是把边给消除掉了,重复此过程,直到能在有限的时间内 消除所有的边 ,则不会发生死锁,否则会发生死锁。(消除边的过程类似于 拓扑排序)
  • 死锁的解除

当死锁检测程序检测到存在死锁发生时,应设法让其解除,让系统从死锁状态中恢复过来,常用的解除死锁的方法有以下四种:

  1. 立即结束所有进程的执行,重新启动操作系统 :这种方法简单,但以前所在的工作全部作废,损失很大。

  2. 撤销涉及死锁的所有进程,解除死锁后继续运行 :这种方法能彻底打破死锁的循环等待条件,但将付出很大代价,例如有些进程可能已经计算了很长时间,由于被撤销而使产生的部分结果也被消除了,再重新执行时还要再次进行计算。

  3. 逐个撤销涉及死锁的进程,回收其资源直至死锁解除。

  4. 抢占资源 :从涉及死锁的一个或几个进程中抢占资源,把夺得的资源再分配给涉及死锁的进程直至死锁解除。

操作系统内存管理基础

内存管理介绍

  • 操作系统的内存管理主要是做什么?

操作系统的内存管理主要负责内存的分配和回收,另外地址转换也就是将逻辑地址转换为相应的物理地址等功能也是操作系统内存管理做的事情

常见的几种内存管理机制

  • 内存管理机制有哪几种方式?

简单分为连续分配管理方式和非连续分配管理方式两种。连续分配管理方式是指为一个用户程序分配一个连续的内存空间,常见的如块式管理。同样的,非连续分配管理方式允许一个程序使用的内存分布在离散或者说不连续的内存中,常见的如页式管理和段式管理。

1.块式管理:将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它块,如果程序运行需要很小的空间的话,分配的这块内存很大部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片

2.页式管理:把内存分为大小相等且固定的一页一页的形式,页较小,相比于块式管理的划分粒度更小,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址

3.段式管理 : 页式管理虽然提高了内存利用率,但是页式管理其中的页并无任何实际意义。 段式管理把主存分为一段段的,段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。

4.段页式管理:段页式管理结合了段式管理和页式管理的优点,简单来说段页式管理机制就是把主存先分为若干段,每个段又分为若干页,也就是说段页式管理机制中段与段之间以及段的内部都是离散的

快表和多级页表

  • 快表和多级页表,这两个东西分别解决了页表管理中很重要的两个问题,简要介绍一下:

在分页内存管理中,很重要的两点是:

1.虚拟地址到物理地址的转换要快

2.解决虚拟地址空间大,页表也会很大的问题

快表

为了提高虚拟地址到物理地址的转换速度,操作系统在页表方案基础之上引进快表来加速虚拟地址到物理地址的转换。我们可以把快表理解为一高速缓冲存储器(cache),其中的内容是页表的一部分或者全部内容。作为页表的Cache,它的作用与页表相似,但是提高了访问速率。由于采用页表做地址转换,读写内存数据时CPU访问两次主存。有了快表,有时只需要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。

使用快表的转换流程是这样的:

1.根据虚拟地址中的页号查快表

2.如果该页在快表中,直接从快表中读取相应的物理地址

3.如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表添加到快表中

4.当快表填满后,又要添加新页时,就按照一定的淘汰策略淘汰掉快表中的一个页

多级页表

引入多级页表的主要目的是为了避免将全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保存到内存中。多级页表属于时间换空间的典型场景。

分页机制和分段机制

  • 分页机制和分段机制有哪些共同点和区别?

1.共同点

  • 分页机制和分段机制都是为了提高内存利用率,减少内存碎片
  • 页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内存是连续的

2.区别:

  • 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序
  • 分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好的满足用户的需要

逻辑(虚拟)地址和物理地址

  • 解释一下逻辑地址与物理地址的概念:

我们编程一般只有可能和逻辑地址打交道,比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定。物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。

CPU寻址

  • 简介CPU寻址以及为什么需要虚拟地址空间

现代处理器使用的是一种成为虚拟寻址的寻址方式。使用虚拟寻址,CPU需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。实际上完成虚拟地址转换为物理地址转换的硬件是CPU中含有一个被称为内存管理单元的硬件。如图所示:

为什么要有虚拟地址空间?

如果没有虚拟地址空间的时候,程序直接访问和操作的都是物理内存。这会造成什么问题?

1.用户程序可以直接访问任意内存,寻址内存的每个字节,这样就很容易破坏操作系统,造成操作系统崩溃

2.想要同时运行多个程序变得困难。比如你想同时运行一个微信和一个 QQ 音乐都不行。为什么呢?举个简单的例子:微信在运行的时候给内存地址 1xxx 赋值后,QQ 音乐也同样给内存地址 1xxx 赋值,那么 QQ 音乐对内存的赋值就会覆盖微信之前所赋的值,这就造成了微信这个程序就会崩溃。

总的来说:如果直接将物理地址暴露出来的话会带来严重问题,比如对操作系统造成伤害以及给同时运行多个程序造成困难

通过虚拟地址访问有以下优势:

  • 程序可以通过一系列连续的虚拟地址来访问物理内存中不相邻的大内存缓冲区
  • 程序可以使用一系列虚拟地址来访问大于可用物理地址的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为4kb)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动
  • 不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。

虚拟内存

虚拟内存

  • 什么是虚拟内存

通过虚拟内存可以让程序拥有超过系统物理内存大小的可用内存空间。另外,虚拟内存为每个进程提供了一个一致的,私有的地址空间,它让每个进程产生了一种在独享内存的错觉(每个进程拥有一片连续完整的内存空间)。这样会更加有效地管理内存并减少出错

局部性原理

局部性原理是虚拟内存技术的基础,正是因为程序运行具有局部性原理,才可以只装入一部分程序到内存就开始运行

局部性原理表现在一下两个方面:

1.时间局部性:如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作。

2.空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定范围之内。

时间局部性是通过将近来使用的指令和数据保存到高速缓存存储器中,并使用高速缓存的层次结构实现。空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。虚拟内存技术实际上就是建立了 “内存一外存”的两级存储器的结构,利用局部性原理实现髙速缓存。

虚拟存储器

基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大小大的。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大得多的存储器——虚拟存储器

实际上,我觉得虚拟内存同样是一种时间换空间的策略,你用 CPU 的计算时间,页的调入调出花费的时间,换来了一个虚拟的更大的空间来支持程序的运行。不得不感叹,程序世界几乎不是时间换空间就是空间换时间。

虚拟内存的技术实现

虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。虚拟内存的实现有一下三种方式:

1.请求分页存储管理:建立在分页管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将响应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存去。

2.请求分段存储管理:建立在分段存储管理之上,增加了请求调段功能,分段置换功能。请求分段存储管理方式就如同请求分页存储管理方式一样,在作业开始运行前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段

3.请求段页式存储管理

这里多说一下?很多人容易搞混请求分页与分页存储管理,两者有何不同呢?

请求分页存储管理建立在分页管理之上。他们的根本区别是是否将程序全部所需的全部地址空间都装入主存,这也是请求分页存储管理可以提供虚拟内存的原因,我们在上面已经分析过了。

它们之间的根本区别在于是否将一作业的全部地址空间同时装入主存。请求分页存储管理不要求将作业全部地址空间同时装入主存。基于这一点,请求分页存储管理可以提供虚存,而分页存储管理却不能提供虚存。

不管是上面那种实现方式,我们一般都需要:

  1. 一定容量的内存和外存:在载入程序的时候,只需要将程序的一部分装入内存,而将其他部分留在外存,然后程序就可以执行了;
  2. 缺页中断:如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页面或段调入到内存,然后继续执行程序;
  3. 虚拟地址空间 :逻辑地址到物理地址的变换。

页面置换算法

  • 说说页面置换算法的作用?常见的页面置换算法有哪些?

地址映射过程中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断(缺页中断 就是要访问的不在主存,需要操作系统将其调入主存后再进行访问。 在这个时候,被内存映射的文件实际上成了一个分页交换文件。)

当发生缺页中断时,如果当前内存中并没有空闲的页面,操作系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫做页面置换算法,我们可以把页面置换算法当成是淘汰页面的规则。

  • OPT页面置换算法(最佳页面置换算法):最佳置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若干页面中哪个是未来最长时间内不再被访问的。因此该算法无法被实现。一般作为衡量其他置换算法的方法。

  • FIFO页面置换算法:总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰

  • LRU页面置换算法(最近最久未使用页面置换算法):LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间T,当必须淘汰一个页面时,选择现有页面中其T值最大的,即最近最久未使用的页面加以淘汰。

  • LFU页面置换算法(最少使用页面置换算法):该置换算法选择在之前时期使用最少的页面作为淘汰页。
    就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫做页面置换算法,我们可以把页面置换算法当成是淘汰页面的规则。

  • OPT页面置换算法(最佳页面置换算法):最佳置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若干页面中哪个是未来最长时间内不再被访问的。因此该算法无法被实现。一般作为衡量其他置换算法的方法。

  • FIFO页面置换算法:总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰

  • LRU页面置换算法(最近最久未使用页面置换算法):LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间T,当必须淘汰一个页面时,选择现有页面中其T值最大的,即最近最久未使用的页面加以淘汰。

  • LFU页面置换算法(最少使用页面置换算法):该置换算法选择在之前时期使用最少的页面作为淘汰页。

主要信息大致收集完毕,后续会根据面经添加高频面试信息,欢迎在评论区补充知识点

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值