http://www.bilibili.com/video/av6538245html
本篇博客,旨在记录视频学习的要点,因此格式随意, 方便本人往后自考和回忆,有兴趣的朋友能够评论讨论。ios
原文地址http://www.cnblogs.com/clockq/p/10318639.html程序员
OS = Kernel + Shell,是介于底层硬件和应用软件之间的一层软件架构。算法
计算机的快速发展与各个底层硬件的快速发展是分不开的(CPU的计算能力,IO的读写能力和网络带宽)编程
BIOS = Basic Input/Output System数组
graph LR A[BIOS]-->B[Bootloader] B --> C[OS]
POST = Power-On Self-Test缓存
graph LR A[POST]-->B[启动顺序] B-->C[主引导记录]
主引导记录(MBR)= Master Boot Record网络
graph LR A[MBR]-->B[分区表] B-->C[活动分区]
硬盘启动分为三种状况:架构
卷引导记录(VBR)= Volume boot record并发
graph LR A[活动分区]-->B[VBR] B-->C[OS]
启动管理器模式:
graph LR A[MBR]-->B[Grub]
graph LR A[Load /boot/kernel]-->B[run /sbin/init]
graph LR A[外设设置中断标记] --> B[保存现场] B --> C[中断程序处理] C --> D[清除中断标记] D --> E[恢复现场]
graph LR A[保存现场] --> B[异常处理] B --> C[杀死异常程序] B --> D[重启发生异常的程序] C --> E[恢复现场] D --> E[恢复现场]
应用程序没法直接操做硬件,须要OS提供的服务接口来间接调用,例:
C语言的printf()
函数,执行时会调用OS的write()
接口
参考文章http://www.javashuo.com/article/p-gdeeqtlo-mw.html
计算机基本硬件结构 = CPU + 内存 + 外设
CPU = 运算器 + 寄存器 + 控制器 + Cache(L1 + L2)+ 存储管理单元(MMU)
越是靠近CPU的内存,读取速度越快,由近及远依次是:
CPU寄存器 => Cache => 主存 => 虚拟内存
操做系统在内存管理上要完成的任务:
逻辑地址------(段机制)------->线性地址------(页机制)------->物理地址。
逻辑地址提供了权限检查功能:好比咱们设置逻辑地址和物理地址之间的映射关系时,能够设置某块地址是只读的,只写的,只有CPU处于管理模式时才能访问等。这些功能可让系统的内核,用户程序的运行空间相互独立:用户程序即便出错,也没法破坏内核;用户程序A崩溃了,也没法影响到用户程序B。
graph LR A[C程序.c] --> |编译| B[编译程序.s] B --> |汇编| C[汇编程序.o] C --> |连接| D[执行程序.exe] D --> |加载| E[应有载入内存]
各个步骤的做用:
逻辑地址
,但该地址对硬件而言是不友好的,所以先通过编译,将代码转为语法树,经过符号来描述地址。具体流程以下图:
graph LR A[CPU加载逻辑地址内容] --> B{查看MMU中是否映射了物理地址} B --> |有| L[得到物理地址] B --> |没有| C{到主存中查找是否有物理地址映射表} C --> |有| L L--> D[读取物理地址的内容]
如要分配N byte,在内存中查找第一个可用(>=N)的空闲块,以知足最快分配。
需求:1. 按照地址排序; 2. 分配须要寻找合适的空闲块; 3. 内存回收后,要将相邻块进行合并。
优点:实现简单; 易于产生更大数据块。
劣势:会产生外部碎片; 不肯定性。
如要分配N byte,在内存中查找第一个可用(>=N)的且最小的空闲块,以知足最快分配。更大的利用小空间。
需求:1. 按照剩余空间大小排序; 2. 分配须要寻找 最 合适的空闲块; 3. 内存回收后,要将相邻块进行合并。
优点:实现简单; 适合大量分配小内存。
劣势:重分配慢; 易产生大量微小的外部碎片。
如要分配N byte,在内存中查找第一个可用(>=N)的且最大的空闲块,以知足最快分配。避免出现大量微小空间。
需求:1. 按照剩余空间大小排序(倒序排列); 2. 分配须要寻找 最 合适的空闲块; 3. 内存回收后,要将相邻块进行合并。
优点:适合大量分配中等大小内存。
劣势:重分配慢; 易产生外部碎片; 会破坏大的空闲块,使更大的应用没法分配。
将非运行时应用占用的内存移动到相邻的一处内存,以减小应用间的外部碎片
利用虚拟内存,将非运行时应用占用的内存移动到虚拟内存,以使的运行时应用有更大的空闲空间使用。
优势:
缺点:
为了更好的分离和管理。
使用分断管理机制后,在逻辑地址层面,地址看上去是连续的,而在物理地址层面,能够将不一样的代码段分离出来管理,从而实现共享,管理,权限保护等。
先划分物理内存至固定大小的帧(Frame),用二元组(f,o)表示帧号和帧内偏移;划分逻辑地址空间至相同大小的页(Page),用二元组(p,o)表示页号和页内偏移。帧更像是相框,里面啥也没有,放了照片(逻辑页面)才有意义。
16-bit的地址空间,512byte大小的页帧大小,则物理地址为(3,6)的实际地址是多少?
解:
512 = 2^9 // 页帧须要使用9bit表示 16-9 = 7 // 页号须要使用7bit表示 因此实际物理地址的二进制表示为 0000011 000000110 转为十进制为1542,也能够用 3 * 512 + 6 = 1542
每一个运行程序都有一个页表,属于程序的运行状态,会动态的发生改变。
上述问题,可使用缓存
和间接访问
两种方式解决。
TLB是一块特殊的快表,能够更快的得到物理帧号,且TLB的miss概率能够忽略不计。
页表有个特殊的概念叫驻留位(上图标红的地方),驻留位为0
的表示物理帧号不存在,也就是本页映射无效。
页表反向设计,页表索引以帧号为index,由于物理内存是固定的,而逻辑空间是无限增加的,所以大大减小了页表大小。
优:
弊:
但愿有个很大、很快、很便宜的存储器,最好掉电数据不丢失。所以,贪心的人类想到了利用硬盘。
早期的计算机因为硬件限制,常常会出现内存不够的状况,当时主要经过覆盖技术(只把须要的指令和数据存在内存中)
和交换技术(把暂时不用的指令和数据存到swap中)
。
产生于20世纪80年代,通常用于多道程序系统的DOS操做系统。当时计算机的内存容量大多只有640kb。
在较小的内存容量下运行较大的应用程序,与分区存储管理配合使用。
以下图所示,A程序为常驻应用,但BC程序不会相互调用,DEF程序也不会相互调用,因此就可让以后调用程序内存覆盖以前调用的内存空间。(以模块为粒度覆盖)
通常用于Unix操做系统。
让正在运行或须要运行的程序能够得到更多内存资源。
将暂时没有运行的程序移到外部swap,从而得到更多的物理内存。(以程序为粒度交换)
在有限容量的内存中,以更小的页粒度为单位装入更多更大的程序(对覆盖技术和交换技术的一次融合)。
指程序在执行过程的一个较短期内,所执行的指令地址和指令操做数地址,分别局限在一小块区域。
举例: 对于一个二维数组[1024 * 1024], 对于横向打印和竖向打印,效率差别仍是至关大的!
这种管理方式,是大多数虚拟存储设备的选择,即在页式存储的基础上,增长了请求调页和页面置换功能。
请求调页:应用程序装入内存时,不是一次性载入所有的页片到内存,而是用到哪一个页片载入哪一个帧。(局部加载)
页面置换:在应用运行过程当中,若是发现须要的页片不在内存中,就会发生“断页中断请求”,系统处理这个中断,就会将虚拟内存中的帧加载到物理内存中。(延迟调用)
缺页中断发生时的事件顺序以下:
1) 硬件陷入内核,在堆栈中保存程序计数器。大多数机器将当前指令的各类状态信息保存在特殊的CPU寄存器中。
2) 启动一个汇编代码例程保存通用寄存器和其余易失的信息,以避免被操做系统破坏。这个例程将操做系统做为一个函数来调用。
3) 当操做系统发现一个缺页中断时,尝试发现须要哪一个虚拟页面。一般一个硬件寄存器包含了这一信息,若是没有的话,操做系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在作什么。
4) 一旦知道了发生缺页中断的虚拟地址,操做系统检查这个地址是否有效,并检查存取与保护是否一致。若是不一致,向进程发出一个信号或杀掉该进程。若是地址有效且没有保护错误发生,系统则检查是否有空闲页框。若是没有空闲页框,执行页面置换算法寻找一个页面来淘汰。
5) 若是选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其余进程运行直至磁盘传输结束。不管如何,该页框被标记为忙,以避免由于其余缘由而被其余进程占用。
6) 一旦页框“干净”后(不管是马上仍是在写回磁盘后),操做系统查找所需页面在磁盘上的地址,经过磁盘操做将其装入。该页面被装入后,产生缺页中断的进程仍然被挂起,而且若是有其余可运行的用户进程,则选择另外一个用户进程运行。
7) 当磁盘中断发生时,代表该页已经被装入,页表已经更新能够反映它的位置,页框也被标记为正常状态。
8) 恢复发生缺页中断指令之前的状态,程序计数器从新指向这条指令。
9) 调度引起缺页中断的进程,操做系统返回调用它的汇编语言例程。
10) 该例程恢复寄存器和其余状态信息,返回到用户空间继续执行,就好像缺页中断没有发生过同样。
摘自[https://blog.csdn.net/qq_22238021/article/details/80192776]
操做系统要在下面的四段时间里作与分页相关的工做:进程建立时,进程执行时,缺页中断时和进程终止时。
当在分页系统中建立一个新进程
时,操做系统要肯定程序和数据在初始时有多大,并为它们建立一个页表。操做系统还要在内存中为页表分配空间并对其进行初始化。当进程被换出时,页表不须要驻留在内存中,但当进程运行时,它必须在内存中。另外,操做系统要在磁盘交换区中分配空间,以便在一个进程换出时在磁盘上有放置此进程的空间。操做系统还要用程序正文和数据对交换区进行初始化,这样当新进程发生缺页中断时,能够调入须要的页面。某些系统直接从磁盘上的可执行文件对程序正文进行分页,以节省磁盘空间和初始化时间。最后,操做系统必须把有关页表和磁盘交换区的信息存储在进程表中。
当调度一个进程执行
时,必须为新进程重置MMU,刷新TLB,以清除之前的进程遗留的痕迹。新进程的页表必须成为当前页表,一般能够经过复制该页表或者把一个指向它的指针放进某个硬件寄存器来完成。有时,在进程初始化时能够把进程的部分或者所有页面装入内存中以减小缺页中断的发生,例如,PC(程序计数器)所指的页面确定是须要的。
当缺页中断发生
时,操做系统必须经过读硬件寄存器来肯定是哪一个虚拟地址形成了缺页中断。经过该信息,它要计算须要哪一个页面,并在磁盘上对该页面进行定位。它必须找到合适的页框来存放新页面,必要时还要置换老的页面,而后把所需的页面读入页框。最后,还要备份程序计数器,使程序计数器指向引发缺页中断的指令,并从新执行该指令。
当进程退出
时,操做系统必须释放进程的页表、页面和页面在硬盘上所占用的空间。若是某些页面是与其余进程共享的,当最后一个使用它们的进程终止的时候,才能够释放内存和磁盘上的页面。
在何处保存未加载的帧?
后备存储能够有哪些?
有效存储访问时间(EAT)= Effective Memory Access Time
EAT = 访问时间 * 页表命中率 + 缺页处理时间 * 缺页概率
例子:
访问时间: 10ns 磁盘访问时间:5ms = 5 * 10^6 ns page fault rate:p dirty page rate(页内容改变,同步到虚拟内存几率):q EAT = 10 * (1 - p) + 5 * 10^6 * p * (1 + q)
由上述例子能够看出,变量p对于总体EAT的影响最重要。
缺页概率,是严重影响虚拟内存效率的一个因素,而缺页概率与页面置换算法息息相关。
功能:当缺页中断发生,须要加载新的帧页到内存,但当应用内存已满时,须要选择淘汰物理内存中的帧来给新的帧资源。
目标:尽量的减小页面换进换出次数。
对于常驻内存(如操做系统或其余关键应用)添加锁定标志位,避免换出。
分类:分为局部页面置换和全局页面置换两大类
基本思路:当一个缺页中断发生,须要进行页面置换时,对于当前内存中的每个逻辑页面,计算它下一次被访问时还需等待的时间,从中选择等待时间最长的页面,做为置换页。
评价:该算法没法实现或者说很难实现,由于OS没法预知每一个页面下次访问须要的等待时间,但该算法能够做为其余算法评定的依据。
例图:
基本思路:对于当前内存中的每个逻辑页面,计算它载入内存的时间,从中选择驻留时间最长的页面,做为置换页。
评价:利用链表实现,载入向链尾加,换出删除链表头便可。
例图:
基本思路:选择最久未被使用的帧页,做为置换页。
评价:时间轴上与最优算法相反,符合局部性原理。在最近一段区间内,找到最久未使用的帧。对于记录各页面调用的前后顺序,开销较大,能够利用链表或堆栈实现。
例图:
基本思路:与LRU类似,是FIFO的一种改进。是两者之间的一种平衡。实现是在页面中加入一个访问位
,一个页面载入时,由硬件初始化为0(软件也能够),若是页面被访问,则相应页表项置为1。将各页表项组成一个环形链表,发生缺页中断时,指针循环判断环形链表,若判断的页表项为0,选为置换页,置换并访问新页后,新页表项置为1,指针下移;若判断的页表项为1,则改成0,指针下移。
评价:时间轴上与最优算法相反,符合局部性原理。在最近一段区间内,找到最久未使用的帧。对于记录各页面调用的前后顺序,开销较大,能够利用链表或堆栈实现。
例图:
基本思路:对Clock算法的一个改进,优化Clock算法对修改页面的写入逻辑,引入新位dirty bit
(脏位)来标识内存修改过与虚存不一致。对于脏位为0的页面,没必要进行同步回虚存的一步。而对于脏位为1的页面,多了一次存活机会,与访问位用法同样。
评价:优化Clock算法的换出效率,并利用两个标识位拥有两条命,来增长存活率,加大命中次数。
例图:
基本思路:选择访问次数最少的页为置换页。因此要维护一张表,对每一个页都有个访问计数器。
评价:LRU关注访问过去时间,久的淘汰;LFU关注访问次数,少的淘汰。
Belady(笔勒滴,一个科学家名)在采用FIFO算法时,有时会出现分配的物理页面数增长,缺页率反而提升(命中率反而降低)的反常现象。
例图:
解决:LRU算法
对应用分配了固定的物理页帧,必定程度上限制了系统灵活性,好比同时运行多个程序,但高峰期正好交错开。因此能够根据应用运行的不一样阶段,调整分配的物理页帧,最大化利用系统资源。
工做集:一个进程p当前执行时刻t前,在以前的定长的页面访问工做集窗口△阶段,使用的逻辑页面集合,用二元函数 W(t, △)
表示;随时刻t变化,集合也在变化。 | W(t, △) |
表示集合大小,即页面数目。(一段时间内访问的页面集合)
常驻集:一个进程p在当前时刻t实际驻留在内存中(物理页面)的页面集合。(某时刻访问的页面集合)
常驻集 <= 工做集。
缺页率:“缺页次数” / “内存访问次数”,影响因素:
基本思路:相似LRU最久未用被淘汰,但不一样的是触发事件不一样,当时刻改变时(而非缺页时)就会清理物理页面,准备物理页帧。
例图:
基本思路:在工做集页面置换算法基础上,动态改变时刻窗口(△)大小,即常驻集大小。当缺页率上升时,提升常驻集大小,反之减小。(淘汰的触发时间是缺页时,一次可能淘汰多个页面)
评价:性能好,开销大。
例图:
什么是抖动?
当分配的常驻集小于工做集,使进程产生不少缺页中断,频繁进行换进换出,从而使运行速度变慢的现象叫作抖动问题。
产生缘由?
随着驻留内存中应用的增长,分配给每一个应用的物理页帧(常驻集)持续减小,缺页率随之提升。因此OS要选择运行适当的进程数量,及每一个进程所需页帧数,使并发水平和缺页率达到必定平衡。