操作系统
1.
操作系统
1.1
操作系统基础
1.1.1 什么是操作系统?
1.
操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是计算机的基⽯。
2.
操作系统本质上是⼀个运⾏在计算机上的软件程序 ,⽤于管理计算机硬件和软件资源。
举例:运⾏在你电脑上的所有应⽤程序都通过操作系统来调⽤系统内存以及磁盘等等硬件。
3.
操作系统存在屏蔽了硬件层的复杂性。 操作系统就像是硬件使⽤的负责⼈,统筹着各种相关事项。
4.
操作系统的内核(Kernel)是操作系统的核⼼部分,它负责系统的内存管理,硬件设备的管理,⽂件系统的管理以及应⽤程序的管理。 内核是连接应⽤程序和硬件的桥梁,决定着系统的性能和稳定性。

1.1.2 系统调⽤
⾯试官 :什么是系统调⽤呢? 能不能详细介绍⼀下。
我 :介绍系统调⽤之前,我们先来了解⼀下⽤户态和系统态。
根据进程访问资源的特点,我们可以把进程在系统上的运⾏分为两个级别:
1.
⽤户态(user mode) : ⽤户态运⾏的进程或可以直接读取⽤户程序的数据。
2. 系统态(kernel mode):可以简单的理解系统态运⾏的进程或程序⼏乎可以访问计算机的任何资源,不受限制。
说了⽤户态和系统态之后,那么什么是系统调⽤呢?
我们运⾏的程序基本都是运⾏在⽤户态,如果我们调⽤操作系统提供的系统态级别的⼦功能咋办呢?那就需要系统调⽤了!
也就是说在我们运⾏的⽤户程序中,凡是与系统态级别的资源有关的操作(如⽂件管理、进程控 制、内存管理等),都必须通过系统调⽤⽅式向操作系统提出服务请求,并由操作系统代为完成。
这些系统调⽤按功能⼤致可分为如下⼏类:
1.设备管理:完成设备的请求或释放,以及设备启动等功能。
2.⽂件管理:完成⽂件的读、写、创建及删除等功能。
3.进程控制:完成进程的创建、撤销、阻塞及唤醒等功能。进程通信。完成进程之间的消息传递或信号传递等功能。
4.内存管理:完成内存的分配、回收以及获取作业占⽤内存区⼤⼩及地址等功能。
1.2
进程和线程
1.2.1 进程和线程的区别
1.2.1.1 进程:
进程是资源分配的基本单位。
进程控制块 (Process
Control Block, PCB) 描述进程的基本信息和运行状态,所谓的创建进程和撤销进程,都是指对 PCB 的操作。
1.2.1.2 线程:
线程是独立调度的基本单位。
一个进程中可以有多个线程,它们共享进程资源。
1.2.1.3 区别
Ⅰ 拥有资源
进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。
Ⅱ 调度
线程是独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换,从一个进程中的线程切换到另一个进程中的线程时,会引起进程切换。
Ⅲ 系统开销
由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,所付出的开销远大于创建或撤销线程时的开销。类似地,在进行进程切换时,涉及当前执行进程 CPU 环境的保存及新调度进程 CPU 环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。
Ⅳ 通信方面:
线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要借助 IPC。
1.2.2 进程有哪⼏种状态?
⾯试官 : 那你再说说进程有哪⼏种状态?
我 :我们⼀般把进程⼤致分为 5 种状态,这⼀点和线程很像!
1. 创建状态(new) :进程正在被创建,尚未到就绪状态。
2. 就绪状态(ready) :进程已处于准备运⾏状态,即进程获得了除了处理器之外的⼀切所需资源,⼀旦得到处理器资源(处理器分配的时间⽚)即可运⾏。
3. 运⾏状态(running) :进程正在处理器上上运⾏(单核 CPU 下任意时刻只有⼀个进程处于运⾏状态)。
4. 阻塞状态(waiting) :⼜称为等待状态,进程正在等待某⼀事件⽽暂停运⾏如等待某资源为可⽤或等待
IO 操作完成。即使处理器空闲,该进程也不能运⾏。
5. 结束状态(terminated) :进程正在从系统中消失。可能是进程正常结束或其他原因中断退出运⾏。
![]() |
1.2.3 进程间的通信⽅式
⾯试官 :进程间的通信常⻅的的有哪⼏种⽅式呢?
我 :⼤概有 7 种常⻅的进程间的通信⽅式。
1. 管道/匿名管道(Pipes) :⽤于具有亲缘关系的⽗⼦进程间或者兄弟进程之间的通信。
2. 有名管道(Names Pipes)
:
匿名管道由于没有名字,只能⽤于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘⽂件的⽅式存在,可以实现本机任意两个进程通信。
3. 信号(Signal) :信号是⼀种⽐较复杂的通信⽅式,⽤于通知接收进程某个事件已经发⽣;
4.
消息队列(Message Queuing) :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(⽆名管道:只存在于内存中的⽂件;命名管道:存在于实际的磁盘介质或者⽂件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除⼀个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不⼀定要以先进先出的次序读取,也可以按消息的类型读取.⽐ FIFO
更有优势。消息队列克服了信号承载信息量少,管道只能承载⽆格式字节流以及缓冲区⼤⼩受限等缺。
5. 信号量(Semaphores)
:信号量是⼀个计数器,⽤于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信⽅式主要⽤于解决与同步相关的问题并避免竞争条件。
6. 共享内存(Shared memory)
:使得多个进程可以访问同⼀块内存空间,不同进程可以及时看到对⽅进程中对共享内存中数据的更新。这种⽅式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有⽤的进程间通信⽅式。
7. 套接字(Sockets) : 此⽅法主要⽤于在客户端和服务器之间通过⽹络进⾏通信。套接字是⽀持 TCP/IP 的⽹络通信的基本操作单元,可以看做是不同主机之间的进程进⾏双向通信的端点,简单的说就是通信的两⽅的⼀种约定,⽤套接字中的相关函数来完成通信过程。
1.2.4 进程同步与进程通信很容易混淆,它们的区别在于:
进程同步:控制多个进程按一定顺序执行;
进程通信:进程间传输信息。
1.2.5 线程间的同步的⽅式
⾯试官 :那线程间的同步的⽅式有哪些呢?
我 :线程同步是两个或多个共享关键资源的线程的并发执⾏。应该同步线程以避免关键的资源使⽤冲突。操作系统⼀般有下⾯三种线程同步的⽅式:
1.互斥量(Mutex):采⽤互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有⼀个,所以可以保证公共资源不会被多个线程同时访问。⽐如
Java 中的synchronized 关键词和各种 Lock 都是这种机制。
2.信号量(Semphares):它允许同⼀时刻多个线程访问同⼀资源,但是需要控制同⼀时刻访问此资源的最⼤线程数量
3.事件(Event) Wait/Notify:通过通知操作的⽅式来保持多线程同步,还可以⽅便的实现多线程优先级的⽐较操
1.2.6 进程的调度算法
⾯试官 :你知道操作系统中进程的调度算法有哪些吗?
我 :嗯嗯!这个我们⼤学的时候学过,是⼀个很重要的知识点!
为了确定⾸先执⾏哪个进程以及最后执⾏哪个进程以实现最⼤ CPU 利⽤率,计算机科学家已经定义了⼀些算法,它们是:
1. 先到先服务(FCFS)调度算法 : 从就绪队列中选择⼀个最先进⼊该队列的进程为之分配资源, 使它⽴即执⾏并⼀直执⾏到完成或发⽣某事件⽽被阻塞放弃占⽤
CPU 时再重新调度。
2. 短作业优先(SJF)的调度算法 : 从就绪队列中选出⼀个估计运⾏时间最短的进程为之分配资源,使它⽴即执⾏并⼀直执⾏到完成或发⽣某事件⽽被阻塞放弃占⽤
CPU 时再重新调度。
3. 时间⽚轮转调度算法
:
时间⽚轮转调度是⼀种最古⽼,最简单,最公平且使⽤最⼴的算法,⼜称 RR(Round robin)调度。每个进程被分配⼀个时间段,称作它的时间⽚,即该进程允许运⾏的时间。
4. 多级反馈队列调度算法 :前⾯介绍的⼏种进程调度的算法都有⼀定的局限性。如短进程优先的调度算法,仅照顾了短进程⽽忽略了⻓进程
。多级反馈队列调度算法既能使⾼优先级的作业得到响应⼜能使短作业(进程)迅速完成。,因⽽它是⽬前被公认的⼀种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
5. 优先级调度 : 为每个流程分配优先级,⾸先执⾏具有最⾼优先级的进程,依此类推。具有相同优先级的进程以
FCFS ⽅式执⾏。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
1.3
死锁
1.3.1 死锁发生的必要条件
互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
占有和等待:已经得到了某个资源的进程可以再请求新的资源。
不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
1.3.2
死锁的处理方式
1.3.2.1 鸵鸟策略
1.3.2.2 死锁检测与死锁恢复
利用抢占恢复
利用回滚恢复
通过杀死进程恢复
1.3.2.3 死锁预防
在程序运行之前预防发生死锁。
1. 破坏互斥条件
例如假脱机打印机技术允许若干个进程同时输出,唯一真正请求物理打印机的进程是打印机守护进程。
2. 破坏占有和等待条件
一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。
3. 破坏不可抢占条件
4. 破坏环路等待
给资源统一编号,进程只能按编号顺序来请求资源。
1.3.2.4 死锁避免
安全状态检测
单个资源的银行家算法
多个资源的银行家算法
1.4
操作系统内存管理基础
1.4.1 内存管理介绍
⾯试官: 操作系统的内存管理主要是做什么?
我: 操作系统的内存管理主要负责内存的分配与回收(malloc函数:申请内存,free函数:
释放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
1.4.2 常⻅的⼏种内存管理机制
⾯试官: 操作系统的内存管理机制了解吗?内存管理有哪⼏种⽅式?
我: 这个在学习操作系统的时候有了解过。
简单分为连续分配管理⽅式和⾮连续分配管理⽅式这两种。连续分配管理⽅式是指为⼀个⽤户程序分配⼀个连续的内存空间,常⻅的如
块式管理 。同样地,⾮连续分配管理⽅式允许⼀个程序使⽤的内存分布在离散或者说不相邻的内存中,常⻅的如⻚式管理 和 段式管理。
1. 块式管理 :
远古时代的计算机操系统的内存管理⽅式。将内存分为⼏个固定⼤⼩的块,每个块中只包含⼀个进程。如果程序运⾏需要内存的话,操作系统就分配给它⼀块,如果程序运⾏只需要很⼩的空间的话,分配的这块内存很⼤⼀部分⼏乎被浪费了。这些在每个块中未被利⽤的空间,我们称之为碎⽚。
2. ⻚式管理 :把主存分为⼤⼩相等且固定的⼀⻚⼀⻚的形式,⻚较⼩,相对相⽐于块式管理的划分⼒度更⼤,提⾼了内存利⽤率,减少了碎⽚。⻚式管理通过⻚表对应逻辑地址和物理地址。
3. 段式管理 :⻚式管理虽然提⾼了内存利⽤率,但是⻚式管理其中的⻚实际并⽆任何实际意义。
段式管理把主存分为⼀段段的,每⼀段的空间⼜要⽐⼀⻚的空间⼩很多 。但是,最重要的是段是有实际意义的,每个段定义了⼀组逻辑信息,例如,有主程序段 MAIN、⼦程序段X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。
4. 段⻚式管理机制:段⻚式管理机制结合了段式管理和⻚式管理的优点。简单来说段⻚式管理机制就是把主存先分成若⼲段,每个段⼜分成若⼲⻚,也就是说
段⻚式管理机制
中段与段之间以及段的内部的都是离散的。
1.4.3 分⻚机制和分段机制有哪些共同点和区别呢?
1. 共同点 :
分⻚机制和分段机制都是为了提⾼内存利⽤率,较少内存碎⽚。
⻚和段都是离散存储的,所以两者都是离散分配内存的⽅式。但是,每个⻚和段中的内存是连续的。
2. 区别 :
⻚的⼤⼩是固定的,由操作系统决定;⽽段的⼤⼩不固定,取决于我们当前运⾏的程序。
分⻚仅仅是为了满⾜操作系统内存管理的需求,⽽段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满⾜⽤户的需要。
1.4.4 快表和多级⻚表
⾯试官 : ⻚表管理机制中有两个很重要的概念:快表和多级⻚表,这两个东⻄分别解决了⻚表管理中很重要的两个问题。你给我简单介绍⼀下吧!
我 :在分⻚内存管理中,很重要的两点是:
1. 虚拟地址到物理地址的转换要快。
2. 解决虚拟地址空间⼤,⻚表也会很⼤的问题。
1.4.4.1
快表
为了解决虚拟地址到物理地址的转换速度,操作系统在 ⻚表⽅案 基础之上引⼊了
快表 来加速虚拟地址到物理地址的转换。我们可以把快表理解为⼀种特殊的⾼速缓冲存储器(Cache),其中 的内容是⻚表的⼀部分或者全部内容。作为⻚表的 Cache,它的作⽤与⻚表相似,但是提⾼了访问速率。由于采⽤⻚表做地址转换,读写内存数据时
CPU 要访问两次主存。有了快表,有时只要访问⼀次⾼速缓冲存储器,⼀次主存,这样可加速查找并提⾼指令执⾏速度。
使⽤快表之后的地址转换流程是这样的:
1. 根据虚拟地址中的⻚号查快表;
2. 如果该⻚在快表中,直接从快表中读取相应的物理地址;
3. 如果该⻚不在快表中,就访问内存中的⻚表,再从⻚表中得到物理地址,同时将⻚表中的该映射表项添加到快表中;
4. 当快表填满后,⼜要登记新⻚时,就按照⼀定的淘汰策略淘汰掉快表中的⼀个⻚。
看完了之后你会发现快表和我们平时经常在我们开发的系统使⽤的缓存(⽐如 Redis)很像,的确是这样的,操作系统中的很多思想、很多经典的算法,你都可以在我们⽇常开发使⽤的各种⼯具或者框架中找到它们的影⼦。
1.4.4.2
多级⻚表
引⼊多级⻚表的主要⽬的是为了避免把全部⻚表⼀直放在内存中占⽤过多空间,特别是那些根本就不需要的⻚表就不需要保留在内存中。多级⻚表属于时间换空间的典型场景,具体可以查看下⾯这篇⽂章
多级⻚表如何节约内存:https://www.polarxiong.com/archives/多级⻚表如何节约内存.html
1.4.4.3
总结
为了提⾼内存的空间性能,提出了多级⻚表的概念;但是提到空间性能是以浪费时间性能为基础
的,因此为了补充损失的时间性能,提出了快表(即 TLB)的概念。 不论是快表还是多级⻚表实际上都利⽤到了程序的局部性原理,局部性原理在后⾯的虚拟内存这部分会介绍到。
1.4.5 分⻚机制和分段机制的共同点和区别
⾯试官
: 分⻚机制和分段机制有哪些共同点和区别呢?
我 :
I
同点 :
分⻚机制和分段机制都是为了提⾼内存利⽤率,较少内存碎⽚。
⻚和段都是离散存储的,所以两者都是离散分配内存的⽅式。但是,每个⻚和段中的内存是连续的。
II
区别 :
⻚的⼤⼩是固定的,由操作系统决定;⽽段的⼤⼩不固定,取决于我们当前运⾏的程序。
分⻚仅仅是为了满⾜操作系统内存管理的需求,⽽段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满⾜⽤户的需要。
1.5
逻辑(虚拟)地址和物理地址
⾯试官 :你刚刚还提到了逻辑地址和物理地址这两个概念,我不太清楚,你能为我解释⼀下不?
我: em...好的嘛!我们编程⼀般只有可能和逻辑地址打交道,⽐如在
C 语⾔中,指针⾥⾯存储的数值就可以理解成为内存⾥的⼀个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操
作系统决定。物理地址指的是真实物理内存中地址,更具体⼀点来说就是内存地址寄存器中的地 址。物理地址是内存单元真正的地址。
1.6
CPU 寻址了解吗?为什么需要虚拟地址空间?
⾯试官 :CPU 寻址了解吗?为什么需要虚拟地址空间?
我 :这部分我真不清楚!
于是⾯试完之后我默默去查阅了相关⽂档!留下了没有技术的泪⽔。。。
![]() |
现代处理器使⽤的是⼀种称为 虚拟寻址(Virtual Addressing) 的寻址⽅式。使⽤虚拟寻址,CPU 需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有⼀个被称为 内存管理单元(Memory Management Unit,MMU) 的硬件。如下图所示:
![]() |
1.6.1 为什么要有虚拟地址空间呢?
先从没有虚拟地址空间的时候说起吧!没有虚拟地址空间的时候,程序都是直接访问和操作的都是物理内存 。但是这样有什么问题呢?
1. ⽤户程序可以访问任意内存,寻址内存的每个字节,这样就很容易(有意或者⽆意)破坏操作系统,造成操作系统崩溃。
2. 想要同时运⾏多个程序特别困难,⽐如你想同时运⾏⼀个微信和⼀个
QQ ⾳乐都不⾏。为什么呢?举个简单的例⼦:微信在运⾏的时候给内存地址
1xxx 赋值后,QQ ⾳乐也同样给内存地址 1xxx 赋值,那么 QQ ⾳乐对内存的赋值就会覆盖微信之前所赋的值,这就造成了微信这个程序就会崩溃。
总结来说:如果直接把物理地址暴露出来的话会带来严重问题,⽐如可能对操作系统造成伤害以及给同时运⾏多个程序造成困难。
1.6.2 通过虚拟地址访问内存有以下优势:
程序可以使⽤⼀系列相邻的虚拟地址来访问物理内存中不相邻的⼤内存缓冲区。
程序可以使⽤⼀系列虚拟地址来访问⼤于可⽤物理内存的内存缓冲区。当物理内存的供应量变⼩时,内存管理器会将物理内存⻚(通常⼤⼩为
4 KB)保存到磁盘⽂件。数据或代码⻚
会根据需要在物理内存与磁盘之间移动。
不同进程使⽤的虚拟地址彼此隔离。⼀个进程中的代码⽆法更改正在由另⼀进程或操作系统使⽤的物理内存。
1.7
虚拟内存
1.7.1 什么是虚拟内存(Virtual Memory)?
⾯试官 :再问你⼀个常识性的问题!什么是虚拟内存(Virtual Memory)?
我 :这个在我们平时使⽤电脑特别是 Windows 系统的时候太常⻅了。很多时候我们使⽤点
开了很多占内存的软件,这些软件占⽤的内存可能已经远远超出了我们电脑本身具有的物理内 存。为什么可以这样呢? 正是因为 虚拟内存 的存在,通过 虚拟内存 可以让程序可以拥有超过系统物理内存⼤⼩的可⽤内存空间。另外,虚拟内存为每个进程提供了⼀个⼀致的、私有的地址空 间,它让每个进程产⽣了⼀种⾃⼰在独享主存的错觉(每个进程拥有⼀⽚连续完整的内存空间)。这样会更加有效地管理内存并减少出错。
虚拟内存是计算机系统内存管理的⼀种技术,我们可以⼿动设置⾃⼰电脑的虚拟内存。不要单纯认为虚拟内存只是“使⽤硬盘空间来扩展内存“的技术。虚拟内存的重要意义是它定义了⼀个连续 的虚拟地址空间,并且 把内存扩展到硬盘空间。推荐阅读:《虚拟内存的那点事⼉》
维基百科中有⼏句话是这样介绍虚拟内存的。
![]() |
4.1
局部性原理
⾯试官 :要想更好地理解虚拟内存技术,必须要知道计算机中著名的局部性原理。另外,局部性原理既适⽤于程序结构,也适⽤于数据结构,是⾮常重要的⼀个概念。
我 :局部性原理是虚拟内存技术的基础,正是因为程序运⾏具有局部性原理,才可以只装⼊部分程序到内存就开始运⾏。
![]() |
早在 1968 年的时候,就有⼈指出我们的程序在执⾏的时候往往呈现局部性规律,也就是说在某个较短的时间段内,程序执⾏局限于某⼀⼩部分,程序访问的存储空间也局限于某个区域。
局部性原理表现在以下两个⽅⾯:
1.
时间局部性 :如果程序中的某条指令⼀旦执⾏,不久以后该指令可能再次执⾏;如果某数据被访问过,不久以后该数据可能再次被访问。产⽣时间局部性的典型原因,是由于在程序中
存在着⼤量的循环操作。
2.
空间局部性 :⼀旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问, 即程序在⼀段时间内所访问的地址,可能集中在⼀定的范围之内,这是因为指令通常是顺序
存放、顺序执⾏的,数据也⼀般是以向量、数组、表等形式簇聚存储的。
时间局部性是通过将近来使⽤的指令和数据保存到⾼速缓存存储器中,并使⽤⾼速缓存的层次结构实现。空间局部性通常是使⽤较⼤的⾼速缓存,并将预取机制集成到⾼速缓存控制逻辑中实 现。虚拟内存技术实际上就是建⽴了 “内存⼀外存”的两级存储器的结构,利⽤局部性原理实现髙速缓存。
4.2
![]() |
虚拟存储器
⾯试官 :都说了虚拟内存了。你再讲讲虚拟存储器把!
我 :
![]() |
基于局部性原理,在程序装⼊时,可以将程序的⼀部分装⼊内存,⽽将其他部分留在外存,就可以启动程序执⾏。由于外存往往⽐内存⼤很多,所以我们运⾏的软件的内存⼤⼩实际上是可以⽐计算机系统实际的内存⼤⼩⼤的。在程序执⾏过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调⼊内存,然后继续执⾏程序。另⼀⽅⾯,操作系统将内存中暂时不使⽤的内容换到外存上,从⽽腾出空间存放将要调⼊内存的信息。这样,计算机好像为⽤户提供了⼀个⽐实际内存⼤的多的存储器——虚拟存储器。
实际上,我觉得虚拟内存同样是⼀种时间换空间的策略,你⽤
CPU 的计算时间,⻚的调⼊调出花费的时间,换来了⼀个虚拟的更⼤的空间来⽀持程序的运⾏。不得不感叹,程序世界⼏乎不是时间换空间就是空间换时间。虚拟内存的技术实现
⾯试官 :虚拟内存技术的实现呢?
我 :虚拟内存的实现需要建⽴在离散分配的内存管理⽅式的基础上。
虚拟内存的实现有以下三种⽅式:
1.
请求分⻚存储管理 :建⽴在分⻚管理之上,为了⽀持虚拟存储器功能⽽增加了请求调⻚功能和⻚⾯置换功能。请求分⻚是⽬前最常⽤的⼀种实现虚拟存储器的⽅法。请求分⻚存储管理 系统中,在作业开始运⾏之前,仅装⼊当前要执⾏的部分段即可运⾏。假如在作业运⾏的过
程中发现要访问的⻚⾯不在内存,则由处理器通知操作系统按照对应的⻚⾯置换算法将相应 的⻚⾯调⼊到主存,同时操作系统也可以将暂时不⽤的⻚⾯置换到外存中。
2.
请求分段存储管理 :建⽴在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理⽅式就如同请求分⻚储存管理⽅式⼀样,在作业开始运⾏之前,仅装⼊当前要 执⾏的部分段即可运⾏;在执⾏过程中,可使⽤请求调⼊中断动态装⼊要访问但⼜不在内存
的程序段;当内存空间已满,⽽⼜需要装⼊新的段时,根据置换功能适当调出某个段,以便 腾出空间⽽装⼊新的段。
3. 请求段⻚式存储管理
这⾥多说⼀下?很多⼈容易搞混请求分⻚与分⻚存储管理,两者有何不同呢?
请求分⻚存储管理建⽴在分⻚管理之上。他们的根本区别是是否将程序全部所需的全部地址空间都装⼊主存,这也是请求分⻚存储管理可以提供虚拟内存的原因,我们在上⾯已经分析过了。
它们之间的根本区别在于是否将⼀作业的全部地址空间同时装⼊主存。请求分⻚存储管理不要求将作业全部地址空间同时装⼊主存。基于这⼀点,请求分⻚存储管理可以提供虚存,⽽分⻚存储管理却不能提供虚存。
不管是上⾯那种实现⽅式,我们⼀般都需要:
1.
⼀定容量的内存和外存:在载⼊程序的时候,只需要将程序的⼀部分装⼊内存,⽽将其他部分留在外存,然后程序就可以执⾏了;
2.
缺⻚中断:如果需执⾏的指令或访问的数据尚未在内存(称为缺⻚或缺段),则由处理器通知操作系统将相应的⻚⾯或段调⼊到内存,然后继续执⾏程序;
3.
虚拟地址空间 :逻辑地址到物理地址的变换。
1.8 ⻚⾯置换算法
1.8.1 ⻚⾯置换算法的作⽤?
问题:
地址映射过程中,若在⻚⾯中发现所要访问的⻚⾯不在内存中,则发⽣缺⻚中断
。
缺⻚中断 就是要访问的⻚不在主存,需要操作系统将其调⼊主存后再进⾏访问。
在这个时候,被内存映射的⽂件实际上成了⼀个分⻚交换⽂件。
当发⽣缺⻚中断时,如果当前内存中并没有空闲的⻚⾯,操作系统就必须在内存选择⼀个⻚⾯将其移出内存,以便为即将调⼊的⻚⾯让出空间。⽤来选择淘汰哪⼀⻚的规则叫做⻚⾯置换算法,
我们可以把⻚⾯置换算法看成是淘汰⻚⾯的规则。
1.8.2 常⻅的⻚⾯置换算法有哪些?
1.OPT ⻚⾯置换算法(最佳⻚⾯置换算法) :最佳(Optimal, OPT)置换算法所选择的被淘汰
⻚⾯将是以后永不使⽤的,或者是在最⻓时间内不再被访问的⻚⾯,这样可以保证获得最低的缺⻚率。但由于⼈们⽬前⽆法预知进程在内存下的若千⻚⾯中哪个是未来最⻓时间内不再被
访问的,因⽽该算法⽆法实现。⼀般作为衡量其他置换算法的⽅法。
2.FIFO(First In First Out) ⻚⾯置换算法(先进先出⻚⾯置换算法) : 总是淘汰最先进⼊内存的⻚⾯,即选择在内存中驻留时间最久的⻚⾯进⾏淘汰。
3.LRU (Least Currently Used)⻚⾯置换算法(最近最久未使⽤⻚⾯置换算法)
:LRU算法赋予每个⻚⾯⼀个访问字段,⽤来记录⼀个⻚⾯⾃上次被访问以来所经历的时间
T,当须淘汰⼀个⻚⾯时,选择现有⻚⾯中其 T 值最⼤的,即最近最久未使⽤的⻚⾯予以淘汰。
4.LFU (Least Frequently Used)⻚⾯置换算法(最少使⽤⻚⾯置换算法)
: 该置换算法选择在之前时期使⽤最少的⻚⾯作为淘汰⻚。
1.9
Linux命令
1.9.1 查看cpu
1. 查看物理CPU的个数
#cat /proc/cpuinfo |grep "physical id"|sort |uniq|wc -l
2. 查看逻辑CPU的个数
#cat /proc/cpuinfo |grep "processor"|wc -l
3. 查看CPU是几核
#cat /proc/cpuinfo |grep "cores"|uniq
4. 查看CPU的主频
#cat /proc/cpuinfo |grep MHz|uniq
1.9.2 实现一个装饰器,使得一个类变为单例类
标准的线程安全的单例模式:
//1.私有的构造器
private SingleDemo01(){}
//2.私有的静态属性
private static SingleDemo01 single;
//3.公有的创建实例对象的方法
public SingleDemo01getInstance(){
if(single == null)//2个线程
synchronized(SingleDemo01.class){
if(single == null){
single = new SingleDemo01();
}
}
return single;
}
}








浙公网安备 33010602011771号