图文并茂,一文带你掌握操作系统(含大厂面试题,万字长文,建议收藏)

1、操作系统基础

1.1、操作系统概述
  • 操作系统(Operating System,简称OS)是管理计算机软件和硬件资源的程序,是计算机的基石。(或者说,操作系统是一个运行在计算机上的软件程序,用于管理计算机硬件和软件资源)
  • 操作系统屏蔽了硬件层的复杂性,可类比于硬件运行的管理者,统筹着各种相关事项。
  • 操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。 内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。
    在这里插入图片描述
1.2、系统调用

介绍系统调用之前,先来了解一下用户态和系统态。

1)用户态:用户态运行的进程可以直接读取用户线程的数据
2)系统态:系统态运行的进程或程序几乎不受限制地可以访问计算机的任何资源

  • 我们运行的程序基本都是在用户态,如果需要调用操作系统提供的系统态级别的子功能,就需要用到系统调用。(或者说,在运行的用户程序中,凡是与系统态资源的相关操作,都必须通过系统调用的方式向操作系统提出服务请求,由操作系统统筹执行。)
  • 系统调用按照功能分类如下:

1)设备管理:完成设备的请求或释放,设备的启动等功能。
2)文件管理:完成文件的读、写、创建和删除等功能。
3)内存管理: 完成内存的分配,回收和获取作业占用内存及地址等功能。
4)进程控制:完成进程的创建、撤销、阻塞及唤醒等功能。
5)进程通信:完成进程间的消息传递或信号传递等功能。

2、进程和线程

2.1、进程和线程的区别
  • 进程包含线程,线程是比进程更小的运行单元。一个进程在执行的过程中可以产生多个线程。
  • 各进程基本上都是相互独立的,各线程不一定独立,同一个进程中的线程可能会相互影响,
  • 进程开销大,有利于资源的管理和保护,线程与之相反。
  • 拿JVM中的进程和线程举例:一个进程可以有多个线程,多个线程共享线程的资源(堆和方法区(JDK1.8以及之后的元空间),虚拟机栈、本地方法栈、程序计数器为每个线程所占有。在这里插入图片描述
2.2、进程的五种状态

进程状态转换图解
进程状态详解:

1)创建状态
  • 进程在创建时,会申请一个进程控制块(PCB:是存放进程管理信息和控制信息的数据结构),向其中填写管理和控制进程的信息,完成资源的分配。
  • 如果创建工作无法完成,如资源无法被满足,无法被调度运行,进程就会处于创建状态。
2)就绪状态
  • 进程已经具备运行条件,即进程已获得除处理器资源以外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)就可以运行
3)执行状态(运行状态)
  • 处于就绪状态的进程被调度后,进程在处理器上运行(在单核CPU中,任何时刻只有一个进程处于运行状态)。
4)阻塞状态(等待状态)
  • 正在执行的进程由于某些事件(I/O请求、申请缓存区失败)而暂时无法运行,进程受到阻塞。
  • 即使处理器空闲,处于阻塞状态的进程也无法运行。
  • 在满足请求时,进入就绪状态,等待系统调用。
5)终止状态
  • 进程正常结束,或其他原因中断退出运行,进程就会进入终止状态,从系统中消失。
2.3、进程间的通信方式
1)管道/匿名管道(Pipes)
  • 由于没有名字,故只能用于具有亲缘关系的父子进程间或兄弟进程之间的通信
  • 管道是半双工的,数据只能向一个方向流动,需要双方通信时,应该建立两个管道。
  • 管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据,管道的一端按序将数据写入缓冲区,另一端按序从缓冲区中读出数据。
  • 当缓冲区读空或写满时,由一定的规则控制读进程或写进程进入等待队列,当空的缓冲区有数据写入或写满的缓冲区有数据读出时,就唤醒等待队列中的读进程或写进程进行读写操作。
    在这里插入图片描述
2)有名管道(Names Pipes)
  • 为解决本机上任意两个进程间能够进行通信,提出了有名管道,有名管道严格遵守“先进先出( first in first out)”。
  • 有名管道提供了一个与之关联的路径名,有名管道的名字以磁盘文件的方式存在系统中(其内容存在内存中),只要可以访问该路径名,可以实现本机任意两个进程之间的通信
3)信号(Signal)
  • 信号是Linux系统中用于进程间相互通信或操作的一种机制,用于通知接收进程某个事件已经发生。在任何时刻,信号可以被发送给某个进程,而无需知道该进程的状态。

详情请参考:进程间通信

4)消息队列(Message Queuing)
  • 消息队列是消息的链表,具有特定的格式,存放在内存中由消息队列标识符标识
  • 消息队列和管道的通信数据都采用先进先出的原则。
  • 与管道(无名管道:只存在于内存中的文件,有名管道:存在于实际的磁盘介质或文件系统中)不同的是消息队列存放在内核中,只有在内核重启(操作系统重启)或显示地删除一个消息队列时,该消息队列才会被真正地删除。
  • 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按照消息的类型读取,比FIFO更有优势。
  • 消息队列克服了信号承载量少,(管道)只能承载无格式字节流和受限于缓冲区大小等缺点。
5)信号量(Semaphores)
  • 信号量是一个计数器,用于多进程对共享数据的访问,使得进程之间数据同步。
  • 信号量主要用于解决与同步相关的问题并避免竞争条件
6)共享内存(Shared memory)
  • 共享内存可以说是最有用的进程间通信方式,使得多个进程可以访问同一块内存空间,不同进程可以及时获取其他进程对共享内存中的更新数据。
  • 共享内存需要依靠某种同步操作,如互斥锁和信号量等。
7) 套接字(Sockets)
  • 套接字是支持TCP/IP的网络通信基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,主要用于在客户端和服务器之间通过网络进行通信
  • 套接字是通信双方的一种约定,用套接字中的相关函数来完成通信过程。
2.4、线程间的同步方式
  • 线程同步是指两个或多个关键的共享资源的线程之间的并发执行。在同步线程的过程中应该避免使用关键共享资源而导致的冲突。
  • 操作系统一般会有临界区(Critical Section)、互斥量(Mutex)、信号量(Semphares)、事件(Event)四种方式来实现线程间的同步。
1)临界区(Critical Section)
  • 临界区通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
  • 优点:临界区可以保证在某一时刻只有一个线程能访问共享资源,简洁高效。
  • 缺点:临界区只能用来同步本进程内的线程,而不可以用来同步多个进程中的线程
2)互斥量(Mutex)
  • 互斥量是为协调对某个共享资源的单独访问而设计的,较为复杂,互斥对象只有1个,只有拥有互斥对象的线程才具有访问资源的权限。如 Java 中的 synchronized 关键字和各种 Lock 都采用的是互斥量机制。
  • 互斥量是信号量的一种特殊形式(信号量的最大资源数为1就是互斥量)。
  • 优点:弥补了临界区(不能同步多个进程中的线程)的缺陷,使其可以跨进程同步,即可以在不同应用程序的线程之间实现对资源的安全共享。
  • 缺点:相比于临界区,创建互斥量需要的资源较多;通过互斥量可以按照线程被独占的方式使用。
3)信号量(Semphares)
  • 信号量方式允许多个线程在同一时刻访问统一资源,但需要限制在同一时刻,能访问此资源的最大线程数。信号量适用于对套接字(Socket)程序中线程的同步(跨进程同步),如HTTP服务器对同一时间内访问某一页面的用户数加以限制。
  • 缺点:

信号量机制必须要有公共内存,不能用于分布式操作系统。
使用时,对信号量的操作分散,难以控制,读写和维护较困难,加大了编码负担。
核心操作P-V分散在各个用户程序的代码中,不易控制和管理,不易发现和纠正错误。

4)事件(Event)
  • 通知线程事件的发生,从而启动后继任务的开始。
  • 事件对象用通知操作来保持线程的同步,可以实现不同进程中的线程完成同步操作(跨进程同步)。
线程同步总结:
  • 临界区不是内核对象,只能用于进程内部的线程同步。
    互斥量、信号量是内核对象,可以实现跨进程同步,即实现不同进程间的线程同步。
  • 互斥量可以保证在某一时刻只能有一个线程能访问临界资源
    信号量可以保证在某一时刻有指定数目的线程能访问临界资源。
2.5、进程的调度算法
  • 进程的调度算法是根据系统的资源分配策略所规定分配算法,定义了进程的执行顺序,确保实现CPU的最大利用率。具体的调度算法有如下五种:
1)先到先服务(FCFS)调度算法
  • ​ 先来先服务调度算法(First Come First Service)也称为先进先出或严格排队方案。
  • 每个进程就绪后,会加入就绪队列,选出就绪队列中存在时间最长的进程(选择就绪队列最前面的进程),将其调入内存,必要资源分配给选出的进程,使其投入运行,直到正常结束或因某事件而阻塞,才会释放处理机
  • FCFS算法既可以用于作业调度,也可以用于进程调度,比较适合于长作业/长进程(运行时间长),而不利于短作业/短进程(可能会有较长的等待时间),
2)短作业优先(SJF)调度算法
  • 从后备队列中选出一个或若干个估计运行时间最短的进程(作业)为之分配资源,使其立即执行并一直执行到正常结束或发生某事件而被阻塞而放弃CPU资源后,再重新调度
  • 短作业优先采用的是非抢占策略,原则是选择预计处理时间最短的进程/作业,因此,短作业会越过长作业,跳至队列头。
  • 缺点:

1.该算法对长作业不利,SJF调度算法中长作业的周转时间会增加。
更严重的是,如果有一长作业进入系统的后备队列,由于调度程序总 是优先调度那些 (即使是后进来的)短作业,将导致长作业长期不被调度(饥饿现象)
2.该算法完全未考虑作业的紧迫程度(作业的优先级),因而不能保证紧迫性作业会被及时处理。
3.由于作业的长短只是根据用户所提供的估计执行时间而定的,而用户又可能会有意或无意地缩短其作业的估计运行时间,致使该算法不一定能真正做到短作业优先调度。

3)时间片轮转调度算法( RR:Round robin)
  • 时间片轮转调度是一种简单、公平且使用最广的算法,适用于分时系统。
  • 系统将所有就绪进程按到达时间的先后次序排成队列,调度程序总是选择就绪队列中第一个进程执行,即先来先服务,但仅能运行一个时间片,如100ms。在使用完一个时间片后,即使进程并未完成其运行,它也必须释放出(被剥夺)处理机给下一个就绪的进程而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。
  • 在时间片轮转调度算法中,时间片的大小对系统性能的影响很大。
    如果时间片足够大,以至于所有进程都能在一个时间片内执行完毕,则时间片轮转调度算法就退化为先来先服务调度算法
    如果时间片很小,那么处理机将在进程间过于频繁切换,使处理机的开销增大,而真正用于运行用户进程的时间将减少。
  • 时间片的大小通常由以下因素确定:系统的响应时间、就绪队列中的进程数目和系统的处理能力,应根据这些因素适当选择。
4)多级反馈队列调度算法
  • 多级反馈队列调度算法较为复杂,是对其他调度算法的折中权衡,既能使长作业得到响应,又能使短作业(进程)迅速完成,是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
  • 算法的具体实现:
    在这里插入图片描述

1.设置多级就绪队列,各级队列优先级从高到低,时间片从小到大
2.新进程到达时先进入第1级队列,按FCFS原则排队等待被分配时
间片
,若用完时间片进程还未结束,则进程进入下一级队列队尾。如果此时已经是在最下级的队列,则重新放回该队列队尾
3.只有第k级队列为空时,才会为k+1级队头的进程分配时间片。被抢占处理机的进程会重新放回原队列队尾。

5)优先级调度算法
  • 优先级调度会为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行,可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
  • 根据优先级是否可以动态改变,可以将优先级分为静态优先级和动态优先级。静态优先级在进程创建时就确定,后面一直不变,动态优先级在进程创建时会设置初始值,之后会根据情况动态地改变优先级。
  • 优先级调度使用优先级区分进程或作业的紧急程度和重要程度,适用于实时操作系统如果有优先级较高的进程/作业源源不断地到来,会出现饥饿现象
6)调度算法的分析和比较:

在这里插入图片描述

3、操作系统内存管理

3.1、内存管理的介绍

  • 总的来说,内存管理分为物理内存管理和虚拟内存管理。
  • 物理内存管理需要掌握程序链接和装入、交换技术、连续分配管理方式以及非连续分配管理方式(分页、分段、段页式,后面会详述)。
  • 虚拟内存管理需要掌握请求分页管理方式、页面置换算法页面分配策略、工作集和抖动等。
  • 内存管理的功能:

1)分配和回收内存:(malloc 函数:申请内存,free 函数:释放内存)当作业或进程被创建后,系统会其分配内存空间,当结束后,内存空间也会被回收。
2)地址转换:将程序中的逻辑地址转化为内存中的物理地址。
3)扩充内存:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存
4)存储保护:保证每个作业在自己的内存空间中运行,互不干扰。

3.2、程序的链接和装入:

  • 创建进程,需要先将程序和数据装入内存,将用户源程序变为可在内存中执行的程序,步骤详述如下:

编译:由编译程序将用户源代码编译成若干个目标模块
链接:由链接程序将编译后形成的一组目标模块以及相应的库函数链接在一起,形成完整的装入模块
装入:由装入程序将装入模块装入内存中运行

对用户程序的处理流程程序的装入方式又可分为绝对装入、可重定位装入、动态运行时装入(动态重定位)。详情可参考:操作系统基本功能

3.3、覆盖和交换

1)覆盖
  • 覆盖可以实现使用较小内存运行较大程序。程序在运行的时候并不是任何时候都要访问程序的所有数据和代码,所以可以将用户空间分成一个固定区和如若干个覆盖区。将经常使用的程序段放在固定区(常驻内存),保证不会被调出。而那些互斥使用的程序可以交替使用覆盖区,如果不使用的话,会被调出内存。
  • 程序的层次结构必须由程序员来规定,操作系统完成自动覆盖,但对用户不可见,增加用户负担。
    在这里插入图片描述
2)交换
  • 以内存为参照物,将要执行的进程从辅存调到内存,该过程称为换入。将处于等待(阻塞)状态的进程从内存调到辅存,该过程称为换出。
两者区别
覆盖交换
发生在运行进程的内部模块间(同一程序或进程),实现粒度较小发生在内存进程(不同程序或进程)之间,实现粒度较大
程序员需要给出模块之间的逻辑覆盖关系不需要模块间的逻辑覆盖关系
无法由操作系统实现,需由程序员实现通过操作系统实现

3.4、主要的内存管理机制

3.4.1、连续分配管理方式
1)单一连续分配
  • 将内存划分为系统区和用户区,系统区为操作系统使用,剩下的用户区给进程或作业使用(可类比于系统调用时的系统态和用户态)
  • 适合单道处理系统,操作简单,没有外部碎片,但会有大量内部碎片,造成资源浪费。
2) 固定分区分配
  • 其分配方式有分区大小相等和分区大小不等两种分配方式。
  • 分区大小相等:将内存的用户区分为大小相等的区域,每个进程只能申请一块区域。
  • 分区大小不等:将内存的用户区分为大小不等的区域(较多小区域,适量中等大小的区域,较少的大区域),每个进程可以根据自身大小只能申请一块区域。
3) 动态分区分配
  • 不会预先划分内存区域,当进程被调入内存时,操作系统会根据进程的大小为其动态地建立分区,使得分区的大小正好匹配进程的需要。
  • 随着进程的消亡,内存中会出现很多成段的空间,时间越长,不可利用的外部碎片就会越多,降低内存的利用率。
  • 可以运用分配算法解决动态分区分配产生外部碎片的问题。
3.4.2、非连续分配管理方式
  • 非连续分配允许将程序分散地装入不相邻的内存区域中,根据分区的大小是否固定,又分为 分页存储管理、分段存储管理、段页式存储管理。
1)分页存储管理
  • 在分页存储管理方式中,根据是否要把作业的所有页面装入内存才能运行的标准,方式细分为基本分页存储管理和请求分页存储管理。
  • 固定分区会产生内部碎片,动态分区会产生外部碎片,这两种技术对内存的利用率都比较低。为内存的使用尽量避免碎片的产生,就引入了分页的思想:把主存空间划分为大小相等(较小)、固定的块(页),块(页)是主存的基本单位,每个进程也以块(页)为单位进行划分。
  • 从形式上看,分页管理与大小相等的固定分区分配类似,但分页管理不会产生外部碎片,划分粒度更大,内存利用率更高。
  • 分页管理的逻辑地址结构由页号P和页内偏移量W组成,通过页表对应逻辑地址和物理地址或者说实现页号到物理块号的地址映射)。
    逻辑地址结构
    页表功能
2)分段存储管理
  • 分页管理方式是从计算机的角度考虑设计的,以提高内存的利用率和计算机的性能, 且分页通过硬件机制实现,对用户不可见;而分段管理方式的提出则是考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要。
  • 分段存储管理方式按照用户进程中的自然段划分逻辑空间,其逻辑地址由段号S和段内偏移量W组成,段号和段内偏移量必须由用户显示提供,在髙级程序设计语言中,该工作由编译程序完成。
    分段系统中的逻辑地址结构
  • 每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。用户可以被分为多个段,并分配一段连续的地址空间(段内需要连续,段间不需要连续)。
  • 执行中的进程通过查找段表,找到每个段对应的内存区域。分段存储通过段表来实现逻辑地址和物理地址的对应(或者说实现从逻辑段到物理内存区的映射)。
    在这里插入图片描述
3)段页式存储管理
  • 页式存储管理能有效地提高内存利用率分段存储管理能反映程序的逻辑结构并有利于段的共享,而段页式存储管理结合了页式管理和段式管理的优点。
  • 在段页式系统中,作业的地址空间先被划分为若干逻辑段,每个段都有自己的段号,然后再将每一段分成若干大小固定的页
    段页式管理方式
4)分页管理和分段管理的异同
  • 共同点

(1)分页管理和分段管理都能提高内存利用率,减少内存碎片。
(2) 页与页、段与段之间都是离散存储的,但每个页、每个段中的内存都是连续的,分页存储和分段存储都采用离散分配内存的方式。

  • 不同点

(1)页的大小是固定的,由操作系统决定。
段的大小不是固定的,由当前运行的程序决定。
(2) 分页仅仅是为了操作系统对于内存管理的需求。
而段是逻辑信息的单位,在程序中体现为代码段、数据段,可以更好地满足用户的需求。

内存管理方式虽然知识点很多,但规律性较强,其方式中有很多相似的地方,可以多多比较、归纳来学习。如,页、段的逻辑地址结构(都是由各自的编号+偏移量),页表、段表以及段页式管理都是为了实现逻辑地址到物理地址的映射等。

5)补充
虚拟地址和物理地址
  • 虚拟地址,又称为逻辑地址,由操作系统决定,在C语言中,指针中存储的数值就是对象在内存中的逻辑地址。
  • 物理地址,是真实物理内存中的地址(内存单元的真实地址),即在地址寄存器中的地址。
3.4.3、快表和多级页表

此处算是对分页存储管理的补充,为避免前面篇幅过长而产生不好的阅读体验,我就拆开来讲解。

  • 在分页存储管理中,需要重点关注两个问题:

A、虚拟地址到物理地址的转换要快。
B、虚拟地址和页表都较大的问题。

1)快表(TLB:translation lookasider buffer)
  • 为了解决虚拟地址到物理地址的转换速度,操作系统在页表的基础上引入快表。快表可以理解为一种特殊的高速缓冲存储器(提高访问速度),类似于Redis,其内容是页表的一部分或全部内容。
  • 由于采用页表完成地址转换,读写内存数据时,CPU需要两次访问主存,但有了快表,有时只要访问一次快表(缓存命中),一次主存,就可以完成指令的执行,提高访问效率。
  • 使用快表之后的地址转换流程:

(1)根据虚拟地址中的页号查快表
(2)如果该页在快表中,直接从快表中读取相应的物理地址
(3)如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中
(4)当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页

2)多级页表
  • 引入多级页表是为了避免将全部页表(特别是根本不需要的页表)一直放在内存中,导致占用空间过多,属于时间换空间的典型场景。

  • 多级列表的逻辑地址由页目录号、页号和页内偏移量组成。
    页目录表的每一项对应一个页表,然后再根据页表找到对应的页。类似于根据书的目录查找章节,目录处有一个章目录(页目录表)和节目录(页表),如果要查找某一节的内容首先找到这一章的地方,然后再查具体的某一节。

  • 多级列表能节省大量内存;并且保证了章目录和节目录都是连续的,因此,可以使用偏移量的形式查找对应的章节。
    在这里插入图片描述详情可参考:

  • 多级页表如何节约内存多级页表详述

总结
  • 为了提高内存的空间性能,提出了多级页表的概念。
    多级列表提升空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表(即 TLB)的概念。
  • 不论是快表还是多级页表实际上都利用到了程序的局部性原理(时间局部性和空间局部性),局部性原理在后面的虚拟内存这部分会介绍到。

4、虚拟内存

4.1、什么是虚拟内存?

  • 虚拟内存,又称为虚拟存储器(VirtualMemory),为每个进程提供了私有的地址空间,能让每个进程产生自己在独享主存的错觉(拥有一片完整连续的可用内存),可以有效管理内存并避免出错。但实际上,虚拟内存通常会被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上。
  • 在很多情况下,计算机的运行程序所占用的内存,可能会远远超过计算机本身的物理内存,但还是可以正常运行各程序,就是得益于虚拟内存的存在,通过虚拟内存,可以让程序可以拥有超过系统物理内存的可用内存空间
  • 基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。由于外存比内存大很多,运行应用的内存大小实际上比计算机系统实际的内存还大。
  • 在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存(换入),然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上(换出),从而腾出空间存放将要调入内存的信息。如此,计算机为用户提供了一个比实际内存大的多的存储器——虚拟存储器
  • 虚拟内存算是一种时间换空间的策略,即用CPU的计算时间、页面的换入换出时间来获取更大的空间来支持内存的运行。

4.2、虚拟内存的技术实现

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

请求分页存储管理不要求将作业全部地址空间同时装入主存,因此,可以提供虚拟内存,分页存储管理反之。

2)请求分段存储管理
  • 建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就同请求分页储存管理方式一样,唯一不同的是换入换出的基本单位不再是页面,而是段。
3)请求段页式存储管理
  • 结合请求分存储和请求分段存储的优势,更加细粒度地、有选择性地实现虚拟内存技术。
4)技术实现的要求
  • 一定容量的内存和外存:
    程序执行时,只需要将程序的一部分装入内存,就可以运行
  • 缺页中断:
    若需要执行的程序未在内存中(即“缺页/段”),则处理器会通知操作系统将相应的页/段调入到内存中,与此同时也会将不常用的页/段调出到外外存中
  • 地址转换:
    逻辑地址转化为物理地址(通过地址转换机构)

4.3、局部性原理

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

1)时间局部性
  • 如果程序中的某条指令一旦执行,不久之后该指令可能会再次执行;如果某数据被访问过,则不久之后,该数据可能会再次被访问
  • 时间局部性的典型原因是在程序中存在着大量的循环操作
  • 时间局部性是将最近使用的指令和数据保存到高速缓存存储器中,并由其层次结构实现。
2)空间局部性
  • 一旦程序访问了某个存储单元,在不久之后,附近的存储单元也会被访问(程序在一段时间内所访问的地址可能集中在一定的范围内,因为指令通常是顺序存放、顺序执行的,数据通常是以向量、数组、表的形式聚簇存储),或者说,CPU访问存储器时,访问的存储单元都趋于聚集在一个较小的连续区域中。

  • 空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。

  • 虚拟内存技术实际上就是建立了 “内存一外存”的两级存储器的结构,利用局部性原理实现高速缓存。

4.4、页面置换算法

  • 当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间,而用来选择淘汰哪一页的规则叫做页面置换算法
1)最佳(OPT)页面置换算法

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

2)先进先出(FIFO)页面置换算法 :
  • FIFO(First In First Out)算法基于队列实现,总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。
  • FIFO算法会产生当所分配的物理块数增大而页故障数不减反增的异常现象(Belady现象)
3)最近最久未使用(LRU)页面置换算法
  • LRU(Least Recently Used)算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T,当须淘汰一个页面时,选择现有页面中其 T 值最大的,即最近最久未使用的页面予以淘汰。
  • LRU算法是堆栈类算法,性能较好,不可能出现Belady异常,但需要寄存器和栈的硬件支持
4) 最少使用(LFU )页面置换算法

LFU(Least Frequently Used)算法选择在之前时期使用最少的页面作为淘汰页(依据局部性原理)。

5) 时钟(CLOCK)置换算法

LRU算法的性能接近于OPT,但是实现起来比较困难,且开销大;FIFO算法实现简单,但性能差。所以操作系统的设计者尝试了很多算法,试图用比较小的开销接近LRU的性能,这类算法都是CLOCK算法的变体。
详情可以参考:操作系统之页面置换算法

4.5、驻留集、工作集和抖动

1)驻留集
  • 驻留集:进程已装入内存的页面的集合,与系统采用的页面装入和页面置换算法有关。
  • 驻留集尺寸:进程驻留在内存中的页面数量,与系统采用的页面分配策略有关。
    在这里插入图片描述
2)工作集
  • 工作集是在某段时间间隔内进程运行所需访问的页面的集合,可用于指导驻留集大小。
  • 在进程执行期间可以容易地确定进程对存储空间的需求(工作集尺寸)。操作系统可以用这种方法决定给哪个进程分配更多的帧,哪个进程应当让出一些帧。
3)抖动
  • 由于虚拟存储器系统能从逻辑上扩大内存,人们希望在系统中能运行更多的进程,即增加多道程序度,以提高处理机的利用率。
  • 如果多道程序度过高,页面在内存与外存之间频繁调度(换入和换出),以至于调度页面所需时间比进程实际运行的时间还多,此时系统效率急剧下降,甚至导致系统崩溃。这种现象称为颠簸或抖动(thrashing)
    抖动
4)抖动的预防策略
  • 采取局部置换策略,以防止抖动扩散

仅允许进程在自身范围内进行置换。即使发生抖动,也可以把影响限制在较小范围内。

  • 在处理机调度中引入工作集策略

操作系统跟踪每个进程的工作集,并为进程分配大于其工作集的物理块。如果所有工作集之和增加到超过了可用物理块的总数,操作系统会暂停一个进程,将其页面调出并且将其物理块分配给其他进程,防止出现抖动现象。

  • 用L=S准则调节缺页率

L是产生缺页的平均时间,S是系统处理缺页的平均时间。理论证明,当I=S时,磁盘和处理机到可以达到最佳利用率,但在实际系统中很难实现。

  • 挂起若干进程

参考:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值