存储器
构造:寄存器、高速缓存、内存、磁盘、磁带 顶层的容量越少,但是速度越快
磁盘的容量更大,但是它的随机访问速度比内存低了三个数量级,其低俗的原因是它是一个机械装置并且有一个特殊的构造。
每个磁盘有多个盘面,然后以一定的速度旋转着,然后边缘有一个机械臂,每个盘面上都会有一个磁头来读取数据。它的每个磁道会有多个扇区。机械臂从一个柱面移动到另一个随机柱面的时间是5ms到10ms。到了指定的柱面之后,还要等扇区旋转到磁头之下,这样才能开始读写。硬盘的读取速率为50MB/S-160MB/S。
内核
计算机是由各种硬件设备组成的,比如内存、CPU、硬盘等,如果让每个应用程序都和这些硬件设备进行通信的话就过于麻烦了,所以就通过内核来作为应用软件和硬件的中间人来负责,应用程序只需要关心和内核的交互,不需要管硬件设备。内核就是操作系统中的一个程序模块,具有访问硬件设备和内存空间的权限。
什么是内核态和用户态
既然是应用程序,那么要运行的话就需要分配CPU时间片。而CPU上能运行的程序分为两种,一种是系统程序,另一种是应用程序,前者具有管理资源和分配的权限,而后者只能向系统申请使用资源。
- 内核态:当CPU处于内核态时,也就是操作系统管理程序运行时所处的状态。运行在内核态的程序可以访问计算机的任何资源。
- 用户态:应用程序都在用户态运行的,也就是用户态提供了应用程序运行的空间。此时的应用程序只能访问当前CPU上执行程序所在的地址空间。 在实际的运行中,CPU会在内核态和用户态之间不断切换。因为应用软件执行的空间必须依赖于内核提供的资源,包括CPU资源、IO资源、存储资源等。为了使上层应用程序能够访问到这些资源,内核空间必须为上层应用提供访问的接口,即系统调用。 上下文切换不仅包括虚拟内存、栈、全局变量等用户资源,还包括了内核堆栈、寄存器等内核资源空间。进程是由内核进行管理和调度的,所以只能是内核态转换到用户态。
上下文切换场景
- 当某个进程的CPU时间片消耗完了之后,进程从运行态转化为就绪态。
- 进程在系统资源不足的时候,内存不够停止运行。
- 系统调用sleep方法之后,进程从运行态转化为阻塞状态。
用户态和内核态切换
- 用户态切换到内核态:异常、中断、系统调用 异常:CPU在执行运行在用户态的程序的时候,发生了异常,就会切换到处理此异常的内核态的程序上。 系统调用:用户态进行主动切换到内核态的一种方式。 中断:IO完成中断。
- 内核态切换到用户态:设置程序状态字
虚拟内存
- 虚拟内存不是实际存在的东西,它的目的是为了缓和大程序和小内存的矛盾,为了让物理内存扩展为更大的逻辑内存,从而使程序获得更多的内存地址。
- 为了更好的管理内存,操作系统把内存抽象成了地址空间,每个进程都有自己的地址空间。然后地址空间分为许多个段,每个段称为一页。这些页被映射到物理地址空间,但不需要映射到连续的物理内存中,也不是所有的页都需要映射。
- 这样的话,虚拟内存就允许程序不需要将所有的虚拟地址空间的每一页映射到物理地址空间,也就不用让程序全部调入内存就可以运行,因此一个程序如果大小为0-64K,计算机只有32K的物理地址,用虚拟内存技术就可以运行这个程序。
分页地址映射
操作系统引入了虚拟内存,进程持有虚拟内存会通过CPU的内存管理单元MMU的映射关系,来转换成物理地址,然后通过物理地址来访问内存。主要有两种方式,内存分段和内存分页
内存分页
分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小,这样一个连续并且固定尺寸大小的内存空间就成为页。(这样额度话释放是以页为单位的,不会产生进程无法使用的小的内存空间) 虚拟地址通过页表来映射成物理地址。
页表存储在内存管理单元MMU中
在分页机制下,虚拟地址由页号和偏移量组成,页号就是索引,通过偏移量就可以找到对应的物理内存地址。
页面置换算法
- 我们在程序运行的时候,不需要一次性把所有程序都加载到物理地址上,而是当程序运行的时候,需要用到虚拟内存中的指令和数据的时候,才把它加载到物理地址上。
- 当进程访问的虚拟地址在页表中查询不到的话,系统就发生了缺页异常。进入系统的内核空间,重新分配物理地址,再更新页表,然后返回用户空间,恢复进程的运行。如果内存空间已满的话,就需要根据某种算法来淘汰某个页面,以便装入新的页面。 最佳替换(OPT):所选择的页面是最近最长时间不被使用的页面,是一种理论的算法,因为不知道哪个页面最长时间不会被使用。 最近最久未使用(LRU):就是虽然不知道以后的情况,但是以前最近最久没有被使用的就可以淘汰。实现LRU需要用一个链表,当一个页面被使用的时候,就把这个页面放到链表的表头。因此每次访问都需要更新表头,所以实现LRU的代价很高。 先进先出(FIFO):选择置换出的页面是最先进入的页面,该算法会使那些经常被使用的页面被换出,从而使缺页率升高。
内存分段
- 程序是由若干个逻辑分段组成的,所以内存分段的话,就分成了代码段,数据段、堆段和栈段。每个段的大小不同,并且可以动态的增长。
- 分段机制下,虚拟地址是由段选择因子(有段号和特权等标志位)和段内偏移量组成的。可以通过段基地址和段内偏移量得到物理内存地址。
缺点
- 会造成内存碎片的问题:即释放的内存空间是不连续的,这样的话就无法运行一个比较大的程序。
- 内存之间的交换的效率低的问题 当内存空间中不连续的小内存过多的情况,就可以通过交换来解决内存碎片问题。先把A程序写到硬盘上,然后再从硬盘写到与大程序挨着的地方。因为内存分段会经常导致内存碎片的产生,而与硬盘之间的交互的速度比较慢,所以会导致性能瓶颈。
段页式内存管理
先分成多个有逻辑意义上的段,然后再把每个段分成多个页,也就是对分段划分出来的连续空间,再分成多个固定大小的页。 这样,地址结构就由段号、段内页号和段内偏移量组成。段页式的地址变换的数据结构是先有一个段表,每个段中又有一个页表,每个段表中的地址是页表的起始地址,再通过页表地址是某个页的物业页号。
第⼀次访问段表,得到⻚表起始地址;
第⼆次访问⻚表,得到物理⻚号;
第三次将物理⻚号与⻚内位移组合,得到物理地址。