目录
- ⼀、操作系统基础
- 1.1 什么是操作系统?
- 1.2 系统调用
- 1.3 并行与并发
- 1.4 死锁
- ⼆、进程和线程
- 2.1 进程和线程的区别
- 2.2 进程有哪⼏种状态?
- 2.3 进程间的通信⽅式
- 2.4 线程间的同步的⽅式
- 2.5 进程的调度算法
- 三、操作系统内存管理基础
- 3.1 内存管理介绍
- 3.2 常⻅的⼏种内存管理机制
- 3.3 快表和多级⻚表
- 3.4 分⻚机制和分段机制的共同点和区别
- 3.5 逻辑(虚拟)地址和物理地址
- 3.6 CPU 寻址了解吗?为什么需要虚拟地址空间?
- 四 虚拟内存
- 4.1 什么是虚拟内存(Virtual Memory)?
- 4.2 局部性原理
- 4.3 虚拟存储器
- 4.4 虚拟存储器的技术实现
- 4.5 ⻚⾯置换算法
- 五、IO(未完待更新)
- 5.1 I/O多路复用
如果有错,欢迎评论区指正
⼀、操作系统基础
1.1 什么是操作系统?
👨💻 ⾯试官 : 先来个简单问题吧!什么是操作系统?
👦 我 :我通过以下四点向您介绍⼀下什么是操作系统吧!
- 操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是计算机系统 的内核与基⽯;
- 操作系统本质上是运⾏在计算机上的软件程序 ;
- 操作系统为⽤户提供⼀个与系统交互的操作界⾯ ;
- 操作系统分内核与外壳(我们可以把外壳理解成围绕着内核的应⽤程序,⽽内核就是能操作硬件 的程序)
关于内核多插⼀嘴:内核负责管理系统的进程、内存、设备驱动程序、⽂件和⽹络系统等等,决定着系统的性能和稳定性。是连接应⽤程序和硬件的桥梁。 内核就是操作系统背后⿊盒的核⼼。
1.2 系统调用
👨💻 ⾯试官 :什么是系统调⽤呢? 能不能详细介绍⼀下。
👦 我 :介绍系统调⽤之前,我们先来了解⼀下⽤户态和系统态。
根据进程访问资源的特点,我们可以把进程在系统上的运⾏分为两个级别:
- ⽤户态(user mode) : ⽤户态运⾏的进程或可以直接读取⽤户程序的数据。
- 系统态(kernel mode):可以简单的理解系统态运⾏的进程或程序⼏乎可以访问计算机的任何资源,不受限制。
说了⽤户态和系统态之后,那么什么是系统调⽤呢?
我们运⾏的程序基本都是运⾏在⽤户态,如果我们调⽤操作系统提供的系统态级别的⼦功能咋办呢?那就需要系统调⽤了!
这些系统调⽤按功能⼤致可分为如下⼏类:
- 设备管理。完成设备的请求或释放,以及设备启动等功能。
- ⽂件管理。完成⽂件的读、写、创建及删除等功能。
- 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
- 进程通信。完成进程之间的消息传递或信号传递等功能。
- 内存管理。完成内存的分配、回收以及获取作业占⽤内存区⼤⼩及地址等功能。
1.3 并行与并发
👨💻 ⾯试官 :并行与并发有什么区别? 。
👦 我 :并行与并发是既相似又有区别的两个概念。
- 并行是指两个或多个事件在同一时刻发生。
- 并发是指两个或多个事件在同一时间间隔内发生。
在多道程序环境下,并发是指在一段时间内宏观上有多个程序在同时运行;但在单处理机系统中,每一时刻仅能有一道程序执行,故在微观上这些程序只能分时交替执行。
1.4 死锁
👨💻 ⾯试官 :什么是死锁? 。
👦 我 :死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
追问:死锁的产生条件?
死锁产生的根本原因是多个进程竞争资源时,进程的推进顺序出现不正确。
- 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
- 占有和等待:已经得到了某个资源的进程可以再请求新的资源。
- 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
- 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
又追问:怎么解除死锁?
处理死锁的思路如下:
预防死锁:破坏四个必要条件中的一个或多个来预防死锁。
避免死锁:在资源动态分配的过程中,用某种方式防止系统进入不安全的状态。
检测死锁:运行时产生死锁,及时发现思索,将程序解脱出来。
解除死锁:发生死锁后,撤销进程,回收资源,分配给正在阻塞状态的进程。
⼆、进程和线程
2.1 进程和线程的区别
👨💻 ⾯试官: 好的!我明⽩了!那你再说⼀下: 进程和线程的区别。
👦 我: 好的! 下图是 Java 内存区域,我们从 JVM 的⻆度来说⼀下线程和进程之间的关系吧!
从上图可以看出:⼀个进程中可以有多个线程,多个线程共享进程的堆和⽅法区 (JDK1.8 之后的元空间)资源,但是每个线程有⾃⼰的程序计数器、虚拟机栈 和 本地⽅法栈。
总结: **线程是进程划分成的更⼩的运⾏单位,⼀个进程在其执⾏的过程中可以产⽣多个线程。**线程和进程最⼤的不同在于基本上各进程是独⽴的,⽽各线程则不⼀定,因为同⼀进程中的线程极有可能会相互影响。线程执⾏开销⼩,但不利于资源的管理和保护;⽽进程正相反。
2.2 进程有哪⼏种状态?
👨💻 ⾯试官 : 那你再说说进程有哪⼏种状态?
👦 我 :我们⼀般把进程⼤致分为 5 种状态,这⼀点和线程很像!
- 创建状态(new) :进程正在被创建,尚未到就绪状态。
- 就绪状态(ready) :进程已处于准备运⾏状态,即进程获得了除了处理器之外的⼀切所需资源,⼀旦得到处理器资源(处理器分配的时间⽚)即可运⾏。
- 运⾏状态(running) :进程正在处理器上上运⾏(单核 CPU 下任意时刻只有⼀个进程处于运⾏状态)。
- 阻塞状态(waiting) :⼜称为等待状态,进程正在等待某⼀事件⽽暂停运⾏如等待某资源为可⽤或等待 IO 操作完成。即使处理器空闲,该进程也不能运⾏。
- 结束状态(terminated) :进程正在从系统中消失。可能是进程正常结束或其他原因中断退出运⾏。
2.3 进程间的通信⽅式
👨💻 ⾯试官 :进程间的通信常⻅的的有哪⼏种⽅式呢?
👦 我 :⼤概有 7 种常⻅的进程间的通信⽅式。
- 管道/匿名管道(Pipes) :⽤于具有亲缘关系的⽗⼦进程间或者兄弟进程之间的通信。
- 有名管道(Names Pipes) : 匿名管道由于没有名字,只能⽤于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘⽂件的⽅式存在,可以实现本机任意两个进程通信。
- 信号(Signal) :信号是⼀种⽐复杂的通信⽅式,⽤于通知接收进程某个事件已经发⽣;
- 消息队列(Message Queuing) :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(⽆名管道:只存在于内存中的⽂件;命名管道:存在于实际的磁盘介质或者⽂件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除⼀个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不⼀定要以先进先出的次序读取,也可以按消息的类型读取.⽐ FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载⽆格式字 节流以及缓冲区⼤⼩受限等缺。
5. 信号量(Semaphores) :信号量是⼀个计数器,⽤于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信⽅式主要⽤于解决与同步相关的问题并避免竞争条件。
6. 共享内存(Shared memory) :使得多个进程可以访问同⼀块内存空间,不同进程可以及时看到对⽅进程中对共享内存中数据的更新。这种⽅式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有⽤的进程间通信⽅式。
7. 套接字(Sockets) : 此⽅法主要⽤于在客户端和服务器之间通过⽹络进⾏通信。套接字是⽀持TCP/IP 的⽹络通信的基本操作单元,可以看做是不同主机之间的进程进⾏双向通信的端点,简单的说就是通信的两⽅的⼀种约定,⽤套接字中的相关函数来完成通信过程。
2.4 线程间的同步的⽅式
👨💻 ⾯试官 :那线程间的同步的⽅式有哪些呢?
👦 我 :线程同步是两个或多个共享关键资源的线程的并发执⾏。应该同步线程以避免关键的资源使⽤冲突。操作系统⼀般有下⾯三种线程同步的⽅式:
- 互斥量(Mutex):采⽤互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有⼀个,所以可以保证公共资源不会被多个线程同时访问。⽐如 Java 中的 synchronized 关键词和各种 Lock 都是这种机制。
- 信号量(Semphares) :它允许同⼀时刻多个线程访问同⼀资源,但是需要控制同⼀时刻访问此资源的最⼤线程数量
- 事件(Event) :Wait/Notify:通过通知操作的⽅式来保持多线程同步,还可以⽅便的实现多线程优先级的⽐较。
2.5 进程的调度算法
👨💻 ⾯试官 :你知道操作系统中进程的调度算法有哪些吗?
👦 我 :嗯嗯!这个我们⼤学的时候学过,是⼀个很重要的知识点!
为了确定⾸先执⾏哪个进程以及最后执⾏哪个进程以实现最⼤ CPU 利⽤率,计算机科学家已经定义了⼀些算法,它们是:
- 先到先服务(FCFS)调度算法 : 从就绪队列中选择⼀个最先进⼊该队列的进程为之分配资源,使它⽴即执⾏并⼀直执⾏到完成或发⽣某事件⽽被阻塞放弃占⽤ CPU 时再重新调度。
- 短作业优先(SJF)的调度算法 : 从就绪队列中选出⼀个估计运⾏时间最短的进程为之分配资源,使它⽴即执⾏并⼀直执⾏到完成或发⽣某事件⽽被阻塞放弃占⽤ CPU 时再重新调度。
- 时间⽚轮转调度算法 : 时间⽚轮转调度是⼀种最古⽼,最简单,最公平且使⽤最⼴的算法,⼜称 RR(Round robin)调度。每个进程被分配⼀个时间段,称作它的时间⽚,即该进程允许运⾏的时间。
- 优先级调度 : 为每个流程分配优先级,⾸先执⾏具有最⾼优先级的进程,依此类推。具有相同优先级的进程以 FCFS ⽅式执⾏。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
- 多级反馈队列调度算法 :前⾯介绍的⼏种进程调度的算法都有⼀定的局限性。如短进程优先的
调度算法,仅照顾了短进程⽽忽略了⻓进程 。多级反馈队列调度算法既能使⾼优先级的作业得到响应⼜能使短作业(进程)迅速完成。因⽽它是⽬前被公认的⼀种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
三、操作系统内存管理基础
3.1 内存管理介绍
👨💻 ⾯试官: 操作系统的内存管理主要是做什么?
👦 我: 操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
3.2 常⻅的⼏种内存管理机制
👨💻 ⾯试官: 操作系统的内存管理机制了解吗?内存管理有哪⼏种⽅式?
👦 我: 简单分为连续分配管理⽅式和⾮连续分配管理⽅式这两种。
连续分配管理⽅式是指为⼀个⽤户程序分配⼀个连续的内存空间,常⻅的如 块式管理 。同样地,⾮连续分配管理⽅式允许⼀个程序使⽤的内存分布在离散或者说不相邻的内存中,常⻅的如⻚式管理 、 段式管理和段页式管理。
- 块式管理 : 远古时代的计算机操系统的内存管理⽅式。将内存分为⼏个固定⼤⼩的块,每个块中只包含⼀个进程。这些在每个块中未被利⽤的空间,我们称之为碎⽚。
- ⻚式管理 :把主存分为⼤⼩相等且固定的⼀⻚⼀⻚的形式,⻚较⼩,相对相⽐于块式管理的划分⼒度更⼤,提⾼了内存利⽤率,减少了碎⽚。
- 段式管理 : 段式管理把主存分为⼀段段的,每⼀段的空间⼜要⽐⼀⻚的空间⼩很多 。但是,最重要的是段是有实际意义的,每个段定义了⼀组逻辑信息,例如,有主程序段 MAIN、⼦程序段 X、数据段 D及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。
- 段⻚式管理:段⻚式管理机制结合了段式管理和⻚式管理的优点。简单来说段⻚式管理就是把主存先分成若⼲段,每个段⼜分成若⼲⻚,也就是说 段⻚式管理 中段与段之间以及段的内部的都是离散的。
3.3 快表和多级⻚表
👨💻 ⾯试官 : ⻚表管理机制中有两个很重要的概念:快表和多级⻚表,这两个东⻄分别解决了⻚表管理中很重要的两个问题。你给我简单介绍⼀下吧!
👦 我 :在分⻚内存管理中,很重要的两点是:
- 虚拟地址到物理地址的转换要快。
- 解决虚拟地址空间⼤,⻚表也会很⼤的问题。
快表
为了解决虚拟地址到物理地址的转换速度,操作系统在 ⻚表⽅案 基础之上引⼊了 快表 来加速虚拟地址到物理地址的转换。我们可以把块表理解为⼀种特殊的⾼速缓冲存储器(Cache),其中的内容是⻚表的⼀部分或者全部内容。由于采⽤⻚表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,如果命中只要访问⼀次⾼速缓冲存储器,⼀次主存,这样可加速查找并提⾼指令执⾏速度。
使⽤快表之后的地址转换流程是这样的:
- 根据虚拟地址中的⻚号查快表;
- 如果该⻚在快表中(命中),直接从快表中读取相应的物理地址;
- 如果该⻚不在快表中,就访问内存中的⻚表,再从⻚表中得到物理地址,同时将⻚表中的该映射表项添加到快表中;
- 当快表填满后,⼜要登记新⻚时,就按照⼀定的淘汰策略淘汰掉快表中的⼀个⻚。
多级⻚表
引⼊多级⻚表的主要目的:为了避免把全部⻚表⼀直放在内存中占⽤过多空间,特别是那些根本就不需要的⻚表就不需要保留在内存中。多级⻚表属于时间换空间的典型场景。
总结
为了提⾼内存的空间性能,提出了多级⻚表的概念;但是提到空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表(即 TLB)的概念。 不论是快表还是多级⻚表实际上都利⽤到了程序的局部性原理,局部性原理在后⾯的虚拟内存这部分会介绍到。
3.4 分⻚机制和分段机制的共同点和区别
👨💻 ⾯试官 : 分⻚机制和分段机制有哪些共同点和区别呢?
👦 我 :
1.共同点 :
- 分⻚机制和分段机制都是为了提⾼内存利⽤率,减少内存碎⽚。
- ⻚和段都是离散存储的,所以两者都是离散分配内存的⽅式。但是,每个⻚和段中的内存是连续的。
2.区别 :
- ⻚的⼤⼩是固定的,由操作系统决定;⽽段的⼤⼩不固定,取决于我们当前运⾏的程序。
- 分⻚仅仅是为了满⾜操作系统内存管理的需求,⽽段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满⾜⽤户的需要。
3.5 逻辑(虚拟)地址和物理地址
👨💻 ⾯试官 :你刚刚还提到了逻辑地址和物理地址这两个概念,我不太清楚,你能为我解释⼀下不?
👦 我 : em…好的嘛!我们编程⼀般只有可能和逻辑地址打交道,⽐如在 C 语⾔中,指针⾥⾯存储的数值就可以理解成为内存⾥的⼀个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定。物理地址是内存单元真正的地址。
3.6 CPU 寻址了解吗?为什么需要虚拟地址空间?
👨💻 ⾯试官:CPU 寻址了解吗?为什么需要虚拟地址空间?
👦 我 :现代处理器使⽤的是⼀种称为 虚拟寻址(Virtual Addressing) 的寻址⽅式。使⽤虚拟寻址,CPU 需要
将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。
实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有⼀个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件。如下图所示:
为什么要有虚拟地址空间呢?
没有虚拟地址空间的时候,程序都是直接访问和操作的都是物理内存 。但是这样有什么问题呢?
- ⽤户程序可以访问任意内存,寻址内存的每个字节,这样就很容易(有意或者⽆意)破坏操作系统,造成操作系统崩溃。
- 想要同时运⾏多个程序特别困难,⽐如你想同时运⾏⼀个微信和⼀个 QQ ⾳乐都不⾏。为什么呢?举个简单的例⼦:微信在运⾏的时候给内存地址 1xxx 赋值后,QQ ⾳乐也同样给内存地址1xxx 赋值,那么 QQ ⾳乐对内存的赋值就会覆盖微信之前所赋的值,这就造成了微信这个程序就会崩溃。
总结来说:如果直接把物理地址暴露出来的话会带来严重问题,⽐如可能对操作系统造成伤害以及给同时运⾏多个程序造成困难。
通过虚拟地址访问内存有以下优势:
- 程序可以使⽤⼀系列相邻的虚拟地址来访问物理内存中不相邻的⼤内存缓冲区。
- 程序可以使⽤⼀系列虚拟地址来访问⼤于可⽤物理内存的内存缓冲区。当物理内存的供应量变⼩时,内存管理器会将物理内存⻚(通常⼤⼩为 4 KB)保存到磁盘⽂件。数据或代码⻚会根据需要在物理内存与磁盘之间移动。
- 不同进程使⽤的虚拟地址彼此隔离。⼀个进程中的代码⽆法更改正在由另⼀进程或操作系统使⽤的物理内存。
四 虚拟内存
4.1 什么是虚拟内存(Virtual Memory)?
👨💻 ⾯试官:再问你⼀个常识性的问题!什么是虚拟内存(Virtual Memory)?
👦 我 :**虚拟内存是用硬盘来当作临时内存使用。**这个在我们平时使⽤电脑特别是 Windows 系统的时候太常⻅了。很多时候我们使⽤点开了很多占内存的软件,这些软件占⽤的内存可能已经远远超出了我们电脑本身具有的物理内存。为什么可以这样呢? 正是因为 虚拟内存 的存在,通过 虚拟内存 可以让程序可以拥有超过系统物理内存⼤⼩的可⽤内存空间。另外,虚拟内存为每个进程提供了⼀个⼀致的、私有的地址空间,它让每个进程产⽣了⼀种⾃⼰在独享主存的错觉(每个进程拥有⼀⽚连续完整的内存空间)。这样会更加有效地管理内存并减少出错。
4.2 局部性原理
👨💻 ⾯试官:要想更好地理解虚拟内存技术,必须要知道计算机中著名的局部性原理。另外,局部性原理既适⽤于程序结构,也适⽤于数据结构,是⾮常重要的⼀个概念。
👦 我 :局部性原理是虚拟内存技术的基础,正是因为程序运⾏具有局部性原理,才可以只装⼊部分程序到内存就开始运⾏。
局部性原理表现在以下两个⽅⾯:
- 时间局部性 :如果程序中的某条指令⼀旦执⾏,不久以后该指令可能再次执⾏;如果某数据被访问过,不久以后该数据可能再次被访问。产⽣时间局部性的典型原因,是由于在程序中存在着⼤量的循环操作。
- 空间局部性 :⼀旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在⼀段时间内所访问的地址,可能集中在⼀定的范围之内,这是因为指令通常是顺序存放、顺序执⾏的,数据也⼀般是以向量、数组、表等形式簇聚存储的。
时间局部性是通过将近来使⽤的指令和数据保存到⾼速缓存存储器中,并使⽤⾼速缓存的层次结构实现。空间局部性通常是使⽤较⼤的⾼速缓存,并将预取机制集成到⾼速缓存控制逻辑中实现。虚拟内存技术实际上就是建⽴了 “内存⼀外存”的两级存储器的结构,利⽤局部性原理实现髙速缓存。
4.3 虚拟存储器
👨💻 ⾯试官:都说了虚拟内存了。你再讲讲虚拟存储器吧!
👦 我 :虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量进行扩充的一种存储器系统。在虚拟存储器系统中,作业无需全部装入,只要装入一部分就可运行。
基于局部性原理,在程序装⼊时,可以将程序的⼀部分装⼊内存,⽽将其他部分留在外存,就可以启动程序执⾏。由于外存往往⽐内存⼤很多,所以我们运⾏的软件的内存⼤⼩实际上是可以⽐计算机系统实际的内存⼤⼩⼤的。在程序执⾏过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调⼊内存,然后继续执⾏程序。另⼀⽅⾯,操作系统将内存中暂时不使⽤的内容换到外存上,从⽽腾出空间存放将要调⼊内存的信息。这样,计算机好像为⽤户提供了⼀个⽐实际内存⼤的多的存储器——虚拟存储器。
4.4 虚拟存储器的技术实现
👨💻 ⾯试官:虚拟存储器技术的实现呢?
👦 我 :虚拟存储器的实现需要建⽴在离散分配的内存管理⽅式的基础上。 虚拟内存的实现有以下三种⽅式:
- 请求分⻚存储管理 :建⽴在分⻚管理之上,为了⽀持虚拟存储器功能⽽增加了请求调⻚功能和⻚⾯置换功能。请求分⻚是⽬前最常⽤的⼀种实现虚拟存储器的⽅法。请求分⻚存储管理系统中,在作业开始运⾏之前,仅装⼊当前要执⾏的部分段即可运⾏。假如在作业运⾏的过程中发现要访问的⻚⾯不在内存,则由处理器通知操作系统按照对应的⻚⾯置换算法将相应的⻚⾯调⼊到主存,同时操作系统也可以将暂时不⽤的⻚⾯置换到外存中。
- 请求分段存储管理 :建⽴在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理⽅式就如同请求分⻚储存管理⽅式⼀样,在作业开始运⾏之前,仅装⼊当前要执⾏的部分段即可运⾏;在执⾏过程中,可使⽤请求调⼊中断动态装⼊要访问但⼜不在内存的程序段;当内存空间已满,⽽⼜需要装⼊新的段时,根据置换功能适当调出某个段,以便腾出空间⽽装⼊新的段。
请求分页与分页存储管理两者有何不同呢?
请求分⻚存储管理建⽴在分⻚管理之上。他们的根本区别是是否将程序全部所需的全部地址空间都装⼊主存,这也是请求分⻚存储管理可以提供虚拟内存的原因,我们在上⾯已经分析过了。
它们之间的根本区别在于是否将⼀作业的全部地址空间同时装⼊主存。请求分⻚存储管理不要求将作业全部地址空间同时装⼊主存。基于这⼀点,请求分⻚存储管理可以提供虚存,⽽分⻚存储管理却不能提供虚存。
不管是上⾯那种实现⽅式,我们⼀般都需要:
- ⼀定容量的内存和外存:在载⼊程序的时候,只需要将程序的⼀部分装⼊内存,⽽将其他部分留在外存,然后程序就可以执⾏了;
- 缺⻚中断:如果需执⾏的指令或访问的数据尚未在内存(称为缺⻚或缺段),则由处理器通知操作系统将相应的⻚⾯或段调⼊到内存,然后继续执⾏程序;
- 虚拟地址空间 :逻辑地址到物理地址的变换。
4.5 ⻚⾯置换算法
👨💻 ⾯试官:虚拟内存管理很重要的⼀个概念就是⻚⾯置换算法。那你说⼀下 ⻚⾯置换算法的作⽤?常⻅的⻚⾯置换算法有哪些?
👦 我 :地址映射过程中,若在⻚⾯中发现所要访问的⻚⾯不在内存中,则发⽣缺⻚中断 。
缺⻚中断 就是要访问的⻚不在主存,需要操作系统将其调⼊主存后再进⾏访问。 在这个时候,被内存映射的⽂件实际上成了⼀个分⻚交换⽂件。
当发⽣缺⻚中断时,如果当前内存中并没有空闲的⻚⾯,操作系统就必须在内存选择⼀个⻚⾯将其移出内存,以便为即将调⼊的⻚⾯让出空间。⽤来选择淘汰哪⼀⻚的规则叫做⻚⾯置换算法,我们可以把⻚⾯置换算法看成是淘汰⻚⾯的规则。
- OPT ⻚⾯置换算法(最佳⻚⾯置换算法) :最佳(Optimal, OPT)置换算法所选择的被淘汰⻚⾯将是以后永不使⽤的,或者是在最⻓时间内不再被访问的⻚⾯,这样可以保证获得最低的缺⻚率。但由于⼈们⽬前⽆法预知进程在内存下的若千⻚⾯中哪个是未来最⻓时间内不再被访问的,因⽽该算法⽆法实现。⼀般作为衡量其他置换算法的⽅法。
- FIFO(First In First Out) ⻚⾯置换算法(先进先出⻚⾯置换算法) : 总是淘汰最先进⼊内存的⻚⾯,即选择在内存中驻留时间最久的⻚⾯进⾏淘汰。
- LRU (Least Currently Used)⻚⾯置换算法(最近最久未使⽤⻚⾯置换算法) :LRU算法赋予每个⻚⾯⼀个访问字段,⽤来记录⼀个⻚⾯⾃上次被访问以来所经历的时间 T,当须淘汰⼀个⻚⾯时,选择现有⻚⾯中其 T 值最⼤的,即最近最久未使⽤的⻚⾯予以淘汰。
- LFU (Least Frequently Used)⻚⾯置换算法(最少使⽤⻚⾯置换算法) : 该置换算法选择在之前时期使⽤最少的⻚⾯作为淘汰⻚。
五、IO(未完待更新)
5.1 I/O多路复用
👨💻 ⾯试官:I/O多路复用?
👦 我 :IO多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞应用程序,交出cpu。多路是指网络连接,复用指的是同一个线程。