操作系统-虚拟内存、虚拟地址空间机制

文章目录

  • 操作系统-虚拟内存
    • 先引入问题
      • 问题1
      • 问题2
    • 设计原则-局部性原理
    • 虚拟内存有哪些特征?
    • 虚拟内存技术的实现
      • 请求分页存储管理
        • 页表机制
        • 缺页中断机构
        • 地址变换机构
    • 小结

操作系统-虚拟内存

有关操作系统的设计,都是在解决一个问题,即:如何让计算机高效安全的运行多道程序

先引入问题

问题1

我们先回到单任务操作系统时代,假设我们的计算机只有16M内存,其中0-1M给内核使用,我们从1M开始装载自己的程序:

  • 我们先考虑单任务操作系统:当我像运行程序A的时候:将A加载到1M开始的内存空间
  • 我现在又像运行程序B,由于我们考虑单任务操作系统,没办法将AB同时运行,所以只能将A的程序覆盖掉,将B加载到1M开始的地址空间,实现了覆盖。

单任务太low了,我现在要多任务,那应该怎么实现?

  • 首先既然程序A装载到1M开始的地址空间,那么B装载的时候肯定不能覆盖它
  • 那B装载到哪里?应该装到A的后面,听起来很可靠,但是新问题来了:
  • 我们在编译链接的时候,怎么能保证程序将来运行的时候它所用到的内存位置是空闲的呢?难道每次想运行程序B,都需要看下哪块内存是空的,然后重新编译链接?
  • 而且每个程序我还想运行多个进程实例,例如在浏览器同时打开多个标签,这是多么合理的需求啊!可是这种方式没法实现。

如果想要实现多任务,那么我们的方法就需要满足一个条件:在程序加载之前,我们不能对程序被加载到的内存位置有任何提前的假设,既然不能有任何假设我们还是把所有程序都加载到一个“固定位置”叭。

那试想:这里的“固定位置”如果和“内存中的具体位置”不同,那问题不就解决了嘛,也就是说“固定位置”和“内存中的具体位置”是不同的概念。

为了让上述的方案成为可能,虚拟内存的概念就诞生了,所谓虚拟内存就是在真正的内存之上的一层专门给程序使用的抽象。前者的“固定位置”值的是虚拟内存,后者的“内存中的具体位置”是物理内存地址。

可以举个例子,程序A链接的时候,链接到了0x3000位置。程序B也链接到0x3000,但是装入的时候A装入到0x1000, 程序B装入到了0x3000。前述的0x3000是虚拟地址,后面的是物理地址,至于两个地址如何转换的,交给MMU去做。

有了虚拟内存之后, 程序只需要认为自己运行在虚拟地址上就可以了, 真正运行的时候, 才把虚拟地址映射到物理地址(这件事交给MMU来做)。这样, 我们只要把程序链接到一个固定的虚拟地址, 加载程序的时候把它们加载到不同的物理地址, 并维护好虚拟地址到物理地址的映射关系, 就可以实现我们那个看似不可能的需求了!

这里将的是“虚拟地址”,为何称其为虚拟呢?这是相对真实物理地址来讲的,这个虚拟地址是假的,需要经过一层映射后才能变成真的。

下面讲什么是“虚拟内存”!

问题2

我现在有一个2G的游戏,但是我只有512M的内存,那么我能玩这个游戏嘛?

  • 能玩!
  • 为什么能玩?我们先来思考一个问题:
  • 虽然这个游戏是2G,但是代码在执行的时候每次只执行一个指令叭,既然每次只执行一个指令,那为什么我非得一次性把2G的游戏全部装入内存呢?
  • 显然没必要叭,比如:我们一星期有10门课,那我书包里就得装10本课本?当然没必要,我可以只装一本,上完这节课回家换,当然这很蠢,所以大家只装今天上的课的课本。
  • 那应该设计什么方案才能跑起这个游戏呢?
  • 首先我们总不能一次只装入一条指令(正如不能出门不能装一本书,装今天上的课的书),同理我们一次装入多少条指令呢?
  • 这个要看怎么实现了,这里我以分页方式来讲(现代操作系统都使用分页,而且都尽量规避分段机制),即每次我装入一个页(一天要上的课的课本),如果要跑的指令不在(明天上课的书不在),再去装入相应的页(回家拿明天的书)。

这里所讲的是“虚拟内存”:我们先将程序的一部分放在磁盘中,用的时候再去取,那这部分磁盘也相当于是内存了,称其为虚拟内存。为何称其为虚拟?因为它不是货真价实的内存。

设计原则-局部性原理

局部性原理:包括快表、页高速缓存以及虚拟内存技术中都有局部性原理的影子。

局部性原理之一:时间局部性—程序中的循环操作

  • 如果某条执行被执行,那么不久后该指令还可能被执行。
  • 如果某个数据被访问,那么不久后该数据还可能被访问。
  • 将程序一页一页的调入内存就是利用该局部性原理

局部性原理之二:空间局部性—顺序执行和顺序存储

  • 一旦程序访问了某个存储单元,那么不久后,其附近的存储单元也将被访问。

这里其实可以想到:基于局部性原理去写程序,去组织变量、数据结构会对程序的运行速度有帮助的。

虚拟内存有哪些特征?

  1. 多次性,无需在作业运行时一次性将程序全部装入内存,而是允许被分成多次调入。
  2. 对换性,无需作业运行时一直常驻内存,而是允许在作业运行过程中,进行换进和换出。
  3. 虚拟性,是指从逻辑上扩充内存的容量,使用户所看到的内存容量远大于实际的内存容量。
    所以呢,我的1G游戏能跑在512M的机器上。

虚拟内存技术的实现

再考虑如下几个问题:

问题1:优化一次效率,如何实现上述的部分装入,换进换出才能更高效呢?

  1. 首先考虑一种方法:每次换入都替换地址空间的开头内容,比如我要调入20M的数据,直接覆盖掉内存中的前20M数据,这样实现是否ok呢?
    这样实现存在的问题是:内存中的后半部分会一直处于空闲状态,无法利用,那么如果将其利用起来呢?

  2. 考虑第二种方法:第一种方法效率不高的原因是采用连续的替换规则,如果能采用一种离散的替换规则,即每次不一定非得从头替换,我可以充分考虑内存中的数据分配信息,从而离散地进行分配,分页机制就是离散分配的体现。

问题2:需要的哪些技术支持?

  1. 一定容量的内外存,选取外存中多大的空间作为内存的缓存是有讲究的,在linux下是swap区,在windows下是:操作系统-虚拟内存、虚拟地址空间机制_第1张图片
  2. 页表机制,哪些页在内存哪些不在,需要查表决定。
  3. 中断机构:当需要访问的部分未调入内存,则产生中断,让中断服务程序去调入相关部分
  4. 地址变换机构:实现逻辑地址到物理地址的转换。

问题3:有了以上理解你能解释这个问题吗?当电脑内存慢的时候,电脑卡的要死,点一下要反应半天。

  1. 首先虚拟地址是拿磁盘的一部分当内存来用,即将内存当作磁盘的缓存,内存快、小,磁盘慢、大
  2. 内存满的时候只能拿磁盘上的交换区来用,但是磁盘慢,比内存慢好几个数量级,内存越满,越不好调度,用的虚拟内存即磁盘越多,那速度就越慢了
  3. 归根结底,这个问题的解答在两点:内存小、磁盘慢
  4. 怎么解决呢?最好的解决方法是扩内存条,加大虚拟内存空间也会有效果。现在内存容量8G、16G不是问题,虚拟内存作用在变小,但是有些超大型的游戏,还是需要虚拟内存来支持。

请求分页存储管理

  1. 为了支持虚拟存储器功能而增加了请求调页和页面置换功能。
  2. 在分页系统中,只要求将当前需要的一部分页面装入内存,便可以启动作业运行。在作业执行过程中,当所要访问的页面不在内存时,再通过调页功能将其调入,同时还可以通过置换功能将暂时不用的页面换出到外存上,以便腾出内存空间。
  3. 为了实现请求分页,系统必须提供一定的硬件支持。除了需要一定容量的内存及外存的计算机系统,还需要有页表机制、缺页中断机构和地址变换机构。

页表机制

在这里插入图片描述

增加的四个字段说明如下:

  • 状态位P:用于指示该页是否已调入内存,供程序访问时参考。
  • 访问字段A:用于记录本页在一段时间内被访问的次数,或记录本页最近己有多长时间未被访问,供置换算法换出页面时参考。
  • 修改位M:标识该页在调入内存后是否被修改过。
  • 外存地址:用于指出该页在外存上的地址,通常是物理块号,供调入该页时参考。

缺页中断机构

系统中,所要访问的页面不存在时,便产生一个缺页中断,请求OS调入。
缺页中断与普通中断一样,要经过保存CPU现场,分析终端原因,转入中断处理程序,恢复CPU等几个步骤,但是有不同点:

  • 在指令执行期间产生和处理中断信号,而非一条指令执行完成后,属于内部中断
  • 一条指令执行期间,可能产生多个缺页中断。

地址变换机构

操作系统-虚拟内存、虚拟地址空间机制_第2张图片
其中快表是另外一种机制,可查阅相关资料。

至此,虚拟内存技术已经大致了解,其内部还存在很多内容,比如页面置换算法、页面分配策略等。

小结

  1. 虚拟地址空间:给所有进程提供一致的地址空间,每个进程都认为自己是在独占使用单机系统的存储资源。其实是假象
  2. 虚拟地址空间:保护每个进程的地址空间不被其他进程破坏,隔离了进程的地址访问。
  3. 虚拟内存:把主存作为磁盘的高速缓存,在主存和磁盘之间根据需要来回传送数据,在逻辑上扩充了内存。
  4. 虚拟内存:建立了内存-外存的两级存储器的结构

请求分页存储管理的基本思想:

  • 真正用到某一个页是才给,否则不给
  • 需要想办法区分哪些是已经给的,哪些是没给的,在页表里添加一位用来标识是否给了
  • 相当于将分配行为延迟到缺页中断处理程序中
  • 缺页中断在修改完页表后需要刷新TLB
  • 缺页中断发生时可以查询error code找到原因
  • 引起缺页中断的内存地址存在一个寄存器中

如果需要分配页框时没有空闲页框怎么办?

  • 将一些页置换到磁盘中

如果觉得写的不错,对读者有帮助,可以给笔者点个赞,鼓励一下哦~

操作系统系列博客

你可能感兴趣的:(Linux,南航-操作系统-课堂笔记)