《操作系统 - 清华大学》5 -4:虚拟技术

news2025/1/11 22:37:56

文章目录

  • 0. 虚拟存储的定义
  • 1. 目标
  • 2.局部性原理
  • 3. 虚拟存储的思路与规则
  • 4. 虚拟存储的基本特征
  • 5. 虚拟页式存储管理
    • 5.1 页表表项
    • 5.2 示例

0. 虚拟存储的定义

在这里插入图片描述

1. 目标

虚拟内存管理技术,简称虚存技术。那为什么要虚存技术?在于前面覆盖和交换技术,其实还觉得技术上面还不够理想,还达不到很方便、很高效的内存使用的效果,所以需要能够有些更好的办法。

在这里插入图片描述

  1. 覆盖技术到底什么问题?程序员需要去管理哪些应该覆盖,哪些不应该覆盖,它需要把这个调用关系分析清楚,然后告诉相应的处理单元完成相应工作,这个对程序员负担太大。
  2. 交换技术的力度太大,它是一次以一个程序做一个交换力度,会导致整个系统开销变大。

有时候没必要把整个数据导出,希望是把一小部分导出去,能不能做到这一步? 其实是可以做到,希望通过一种更好的办法,充分地把前面覆盖技术和交换技术的问题解决掉,就是虚存技术。

当然这听起来很好,但它怎么能达到呢?先看看它的目标:
在这里插入图片描述

  1. 它能够像覆盖技术一样,它不是把程序的所有都放在内存中去,只是把程序中一小部分放到内存中去,既然不把所有内容放内存中去,它所需要的空闲空间其实没那么大,另外它跟覆盖技术最大的不同,它的过程由操作系统自动来完成,不需要程序员做出干预。这样可以极大地减轻程序员的负担。内存中存放的内容可以是一小部分和覆盖技术一样。
  2. 内存上也像交换技术一样,它能够实现就是程序在内存中跑之后可以动态地根据当前执行情况来把某些数据直接导出和导入,交换技术的导入导出是以一个程序为力度,是程序间的,那能不能做到不管是在程序间还是程序内都无所谓,以一个更小的力度,比如说以一个页为力度来作为交换单位把它导入导出到内存中去。

看上图可能就可以看出来这特点,有四个程序,操作系统有 CPU 的 MMU 支持,有硬件支持之后,比如分页机制支持,内存中,比如说以 P3为例,它只放了两个内存页,其他的数据全是导在硬盘上去的,那这种情况下,P3 运营时它只用了这两个数据,其它没有用到,既然没用到就没必要放到内存中去,这样的话就可以使得这个程序本来整体运行需要很大空间,但是在某一个有限的时间段内,实际需要一小段空间就够了。这种方法可以实现虚存管理想达到一种理想,这种方法其实通过操作系统和 MMU 是可以做到。

2.局部性原理

需要注意,做到之前由于整个处理过程是完全自动的,也就说它不需要程序介入,那其实表面上不需要,其实还是对程序提出一个要求。什么要求呢?就需要程序具有局部性特征。

在这里插入图片描述

程序的局部性原理是指程序在执行过程中,在一个较早的时间之内它所需要的数据和操作的指令分别局限在一定的区域。 这样就可以实现高效地执行。

局部性存在两个细分的概念,一个时间局部性,一个空间局部性

  • 时间局部性是指,一条指令的一次执行和下一次执行,一个数据的一次访问和下一次访问,都集中在很短的时间之内就完成了。
  • 空间局部性是指,当前指令和临近指令,或者当前访问数据和它临近的数据,都集中在一个区域里面,它们在内存中的位置靠得很近。

程序如果具有时间局部性和空间局部性,认为程序的局部性很好,意味着它执行效率会很高。设计程序的时候需要考虑局部性的特征,如果说程序局部性做得很好,操作系统就可以利用程序局部性的特点来实行高效的虚存管理,可以得到很理想的效果,让程序可以很小的一部分的空间放到内存中去,同时它执行效率很高,达到虚拟内存的理想,访问速度快(在执行过程中基本上就是跟在内存中访问完全一样,而且给执行程序提供很大的虚拟空间),空间大,使用方便(不需要程序员干预)。

也许这时候虚拟空间并没有都放在内存中,只是放在硬盘上,但由于读写硬盘的次数很少,使得整个执行效率还是可以很高,但这需要程序本身局部性的保证。

示例:
  ~  在这里插入图片描述
  ~  
C语言是按照行优先来放置二维数组 ,数组元素大小是4字节,所以一维数组大小为4K.
  ~  在这里插入图片描述

3. 虚拟存储的思路与规则

要实现高效的虚存管理机制,除了操作系统和硬件之外,需要程序具有一定的局部性,如果程序不具有局部性,那么高效机制实现起来就很困难。有了操作系统,有了内存管理单元,有分页机制,或者分段机制,再加上程序具有局部性,怎么实现虚存技术?

在这里插入图片描述
操作系统有了硬件支持(分段或者分页), CPU + MMU 有效地实现分段和分页机制。

在这里插入图片描述
有了分段和分页之后,在分段分页的内存管理之上来实现以页或者以段为单位的虚存管理。

大致流程这样:

  1. 首先装入程序时候,不必将所有代码或者数据放内存中去,而只需将当前需要执行的代码和数据放入到相关的页或者段中去,这样使得一小部分代码和数据放到内存中去了,只要一小部分程序代码在内存中,那就可以让程序执行。

  2. 当然很明显,当执行到一定阶段的时候,它可能接下来需要访问的代码或者数据还在硬盘中,所以会产生访问异常,称之为缺页或缺段异常,产生异常之后,操作系统会得到通知,通知之后,操作系统就会看一看,它如果觉得现在内存还有空间,就会把所需要代码数据从硬盘导到内存中去,那导入内存之后,这条没有访问到的指令可以重新执行,它可以继续往下走了。

  3. 但也有可能这时候内存中没有空间了,那这时候操作系统可能干的事要更复杂一点,它要考虑现在这些被占的这些内存的数据和代码,哪些是将来可能不太会用到的,或者一段时间内不会被访问到的,会把这些代码数据给导到外存中去,这样可以空出更多的空闲空间来放入当前需要的代码数据,继续执行。

    那它的选择也很重要,选择得好,也可以保证将来跟内存访问的读写次数就会少,整体性能开销就会大大减少,整个系统性能就会提高。

4. 虚拟存储的基本特征

在这里插入图片描述

  1. 空间很大。 它把硬盘当成了一个虚拟的空间,实际整个虚空间包含的大小是物理空间加上硬盘合在一起形成了虚拟空间,那这空间就很大。

比如说 CPU 是32位的机器,那么其实它的理论空间可以访问 4G,那其实物理内存可能只有26M,在这种情况下硬盘可以很大,通过硬盘的补充可以实现使得在内存中可以跑多个程序,而且每个程序还都认为它自己占了 4G的空间。
  ~  
这感觉很不错,更大的空间会随便使用,但其实在用的过程中,操作系统会自动根据它的判断,来把程序当前正在用到的代码数据放到内存中去,因为内存只有256M,256M内存还要包含Linux 内核,内核本身是不能被换出的,操作系统内核是常驻内存的,但是内存中运行的用户程序,它们不像操作系统那么关键,所以说它可以根据当时的执行情况来选择一小部分放在内存中执行,通过这种方式可以给每个自然运行的程序一个很大的虚拟地址空间。

  1. 部分交换, 它跟前面交换技术相比,需要注意,它每次换入换出是很规整的,要么一个段要么一个页,基于分段分页机制,分段分页是操作系统管理的,它不需要把整个程序都给换出去。交换力度更小,使得效率会更高。
  2. 不连续性, 不连续体现在它物理内存分配是不连续,同时虚拟内存空间使用也是不连续的,前面讲虚拟内存空间是连续的,由于有换入换出机制,可能把虚拟空间连续的这块区域一部分换出去,换出到外存中去。使得实际执行过程中可能会出现,连续执行到某个阶段的时候,这个页不存在,这个情况下就会产生访问异常,但这个异常没关系,操作系统会自动处理这个情况,会把需要连续执行数据和代码,再从外存中再放到内存中去,使得这个程序继续执行,不连续性体现在,本来所有的数据都应该连续地放在虚拟内存中,由于操作系统要把某些数据和代码换出去,造成所谓的不连续,但没关系,操作系统会帮助把它弥补好,使得程序可以正常去访问。

5. 虚拟页式存储管理

讲完这个特征之后,就要考虑到怎么去实现它,在现有硬件和操作系统管理下,能不能具体实现它?
在这里插入图片描述

首先以页式存储管理的基础来讲解虚拟内存管理。

看上图,左侧是逻辑地址空间,右侧是物理地址空间,左侧右侧以页为单位映射关系是靠页表来维护的,页表里面维护了映射关系,页表项的索引是页号,页表项的内容是页帧号。
  ~  
除了页帧号之外还有几个 bit,bit 其实是有很关键的作用,有 bit 代表页存在或不存在,内存地址访问时,通过查找页表发现对应页表项它的存在位是0,意味着这个虚拟机空间对应的物理空间是没有的,不存在映射关系,就会产生访问异常,那异常机制会用来作为虚拟内存管理的效率手段。

根据当前页式内存管理,再增加两个新的功能,一个是请求调页,第二个是页面置换:

  • 请求调页: 需要访问这个页, 才把这个页调到内存中来。

当一个用户程序需要调入内存运行时,不是把所有程序都放到内存来,而是装入一部分程序,放到个别页里面去,运行时候就有可能出现缺页异常,因为建立映射的时候,只映射一部分内存空间,接下来访问那些数据和代码还没有映射上去会产生异常,因为访问数据或者代码不在内存中,这就需要请求调页,真正访问的时候,不在的时候才发出请求。
  ~  
这时候 CPU 会向操作系统发出缺页异常信号,操作系统接收信号之后,会根据当前产生异常地址来找到对应硬盘或者外存中的地址到底是哪个数据需要被调到内存中去。数据找出来之后再放到相应的物理页去,使得该页可以继续执行。

  • 页面置换: 随着程序执行,占用内存越来越多,可能内存不够用,这时候就需要把某些给换出去,把某些需要的页换进来,那换出去的页是不常用页,换进来页是当前正需要的页,那这换入换出就是置换功能。这个功能实现得好坏决定了整体的效率,后面专门介绍有效的置换算法。

5.1 页表表项

为了能够实现请求校验和页面置换,需要在页表中增加一些位,辅助完成这个功能,4个位是比较重要的。

在这里插入图片描述

本来页表项里面存的最主要是页帧号,为了能够有效实现虚存管理,还需要增加几位:

  1. 第一个位 驻留位:表示是该页在不在内存里面,1 代表该页在内存中,意味着它的逻辑页号一定会有对应的物理页号,若为0 代表是当前逻辑页在内存中没有对应的物业页来支持。它的数据有可能是放在硬盘上,这时候如果访问到这一页,就会产生一次缺页中断,这是所谓驻留位,这很重要,它决定了所访问数据是否在内存。

  2. 保护位: 代表能否访问这个地址。有可能这个页是只读的,那写操作就会产生错误,因为它是只读的。有可能是可读可写的,那这时候写操作没问题。还有可能是可执行的,表示这段区域可以执行,那这时候做具体代码的执行操作是没问题,但是如果这个区域是不可执行的,它只是可读可写的,对这块区域做执行操作也会产生异常。

  3. 修改位: 代表这个页是否被修改过。如果这个页被写过,会被置1,若没被写过,那个页会被置成 0,这很重要。

    如果这页被写过,在内存中就维持这个数据,与之前放在硬盘的数据是不一致的,这时候在做换入换出时候,需要把数据导回到硬盘中,使得硬盘中保持数据和内存数据是一致的。如果修改位是0,意味着对这个页没有做写操作,那么它的数据和当时在硬盘中数据是一样。这时候就不需要做写回,如果把这页给换掉的话,直接释放就 OK 了。因为硬盘中的数据和内存中的数据是一致的,下次需要的时候再从内存中调就行了,通过这个修改为处理可以有效地提高置换功能的效率。

  4. 访问位:,代表这个页最近是否访问过。被访问过,会置成1,没有被访问过,置成0。这个很重要,因为在置换算法中,要把一些页换出去,到底换哪些?应该换当前没有被访问的页,把它换出去,那这个位在一定程上表明当前这个页是否经常被访问,如果这个页经常被访问,它应该置成1,既然它没有被置成1就意味着这个页很长时间没访问了,这个页也许不是将来很近的时间之内要会访问的页,就把这个页给换出去。

所以说这几个 bit 位会有效地帮助后续去做页的置换。

5.2 示例

看下图可以更进一步了解,有了这个位之后会产生现象。
在这里插入图片描述

左边图是它的虚存的页表的映射关系,它一共有64K,每一个页表项代表有4K物理页,X 表示驻留位为0,如果是一个具体的数,代表驻留位为1,那它的映射关系是有效的。

  1. 在这种情况下,如果说做一个访问,比如说想把虚拟的0地址的内容赋给一个寄存器,那查0地址在页表里面对应的映射关系,首先可以看最底下的值为 2,表示驻留位为1,且叶帧号是2,所以 2再乘以一个页大小是 8K,所以说它实际访问的物理地址是8192,这个操作很正常,没问题。
  2. 接下来,把虚拟地址32780的内容读到寄存器里面去。32780 其实对应页表项是第八项,32K ~ 36 k 区间,它里面驻留位设置是0,所以没有对应页帧号,也意味着访问这页会产生缺页异常,根据缺页机制把相应的页从外存中调进来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2248293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MYSQL 表的增删改查(上)

目录 1.新增数据 2.查询数据 一般查询 去重查询 排序查询 关于NULL 条件查询 分页查询 1.新增数据 语法:insert into 表名[(字段1,字段2...)] values (值,值....); 插入一条新数据行,前面指定的列,要与后面v…

OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。

2024-11-22 ,由格拉斯哥大学创建的OSPTrack数据集,目的是通过捕获在隔离环境中执行包和库时生成的特征,包括静态和动态特征,来识别开源软件(OSS)中的恶意指标,特别是在源代码访问受限时&#xf…

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时,突然发现它的一个接口,被另一个服务ip频繁的请求。 按理说,之前设置的是,每隔1分钟请求一次接口。但从日志来看,则是1秒钟请求一次&#xff…

如何寻找适合的HTTP代理IP资源?

一、怎么找代理IP资源? 在选择代理IP资源的时候,很多小伙伴往往将可用率作为首要的参考指标。事实上,市面上的住宅IP或拨号VPS代理IP资源,其可用率普遍在95%以上,因此IP可用率并不是唯一的评判标准 其实更应该关注的…

idea_卸载与安装

卸载与安装 卸载1、设置 -> 应用2、查找到应用,点击卸载3、把删除记录和设置都勾选上4、删除其它几个位置的残留 安装1、下载安装包2、欢迎安装 -> Next3、选择安装目录 -> Next4、创建快捷图标和添加到环境变量5、确认文件夹的名称 -> Install6、完成安…

【Axure高保真原型】天气模板

今天和大家分享天气模板的原型模板,里面包括晴天、多云、阴天、小雨、大雨、暴雨、强雷阵雨、小雪、中雪、大雪、暴雪、雨夹雪、微风、强风、狂风、龙卷风、轻雾、大雾等,后续也可以自行添加。 这个模板是用中继器制作的,所以使用也很方便&a…

深度学习模型:循环神经网络(RNN)

一、引言 在深度学习的浩瀚海洋里,循环神经网络(RNN)宛如一颗独特的明珠,专门用于剖析序列数据,如文本、语音、时间序列等。无论是预测股票走势,还是理解自然语言,RNN 都发挥着举足轻重的作用。…

Prometheus告警带图完美解决方案

需求背景 告警分析处理流程 通常我们收到 Prometheus 告警事件通知后,往往都需要登录 Alertmanager 页面查看当前激活的告警,如果需要分析告警历史数据信息,还需要登录 Prometheus 页面的在 Alerts 中查询告警 promQL 表达式,然…

深入理解 Java 基本语法之运算符

(一)研究背景 在 Java 编程中,运算符是处理数据和变量的基本工具,掌握各种运算符的使用方法对于提高编程效率至关重要。 (二)研究目的 深入理解 Java 基础运算符的概念、分类和作用,通过具体…

iOS 17.4 Not Installed

0x00 系统警告 没有安装 17.4 的模拟器,任何操作都无法进行! 点击 OK 去下载,完成之后,依旧是原样! 0x01 解决办法 1、先去官网下载对应的模拟器: https://developer.apple.com/download/all/?q17.4 …

Flink细粒度的资源管理

Apache Flink致力于为所有应用程序自动导出合理的默认资源需求。对于希望根据其特定场景微调其资源消耗的用户,Flink提供了细粒度的资源管理。这里我们就来看下细粒度的资源管理如何使用。(注意该功能目前仅对DataStream API有用) 1. 适用场景 使用细粒度的资源管理的可能…

Ubuntu20.04运行msckf_vio

文章目录 环境配置修改编译项目运行MSCKF_VIO运行 Launch 文件运行 rviz播放 ROSBAG 数据集 运行结果修改mskcf 保存轨迹EVO轨迹评价EVO轨迹评估流程实操先把euroc的真值转换为tum,保存为data.tum正式评估 报错1问题描述 报错2问题描述问题分析问题解决 参考 环境配…

计算机网络 第4章 网络层

计算机网络 (第八版)谢希仁 第 4 章 网络层4.2.2 IP地址**无分类编址CIDR**IP地址的特点 4.2.3 IP地址与MAC地址4.2.4 ARP 地址解析协议4.2.5 IP数据报的格式题目2:IP数据报分片与重组题目:计算IP数据报的首部校验和(不正确未改) …

Angular面试题汇总系列一

1. 如何理解Angular Signal Angular Signals is a system that granularly tracks how and where your state is used throughout an application, allowing the framework to optimize rendering updates. 什么是信号 信号是一个值的包装器,可以在该值发生变化时…

SAR ADC系列15:基于Vcm-Base的开关切换策略

VCM-Based开关切换策略:采样~第一次比较 简单说明: 电容上下极板分别接Vcm(一般Vcm1/2Vref)。采样断开瞬间电荷锁定,进行第一次比较。 当VIP > VIN 时,同时 减小VIP 并 增大VIN 。P阵列最高权重电容从Vcm(1/2Vref)…

实现Excel文件和其他文件导出为压缩包,并导入

导出 后端&#xff1a; PostMapping("/exportExcelData")public void exportExcelData(HttpServletRequest request, HttpServletResponse response, RequestBody ResData resData) throws IOException {List<Long> menuIds resData.getMenuIds();List<Co…

某车企ASW面试笔试题

01--背景 去年由于工作岗位的动荡&#xff0c;于是面试了一家知名车企&#xff0c;上来进行了一番简单的介绍之后&#xff0c;被告知需要进入笔试环节&#xff0c;以往单位面试都是简单聊聊技术问题&#xff0c;比如对软件开发的流程或者使用的工具等待问题的交流&#xff0c;…

计算(a+b)/c的值

计算&#xff08;ab&#xff09;/c的值 C语言代码C语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给定3个整数a、b、c&#xff0c;计算表达式(ab)/c的值&#xff0c;/是整除运算。 输入 输入仅一行&…

【在Linux世界中追寻伟大的One Piece】多线程(二)

目录 1 -> 分离线程 2 -> Linux线程互斥 2.1 -> 进程线程间的互斥相关背景概念 2.2 -> 互斥量mutex 2.3 -> 互斥量的接口 2.4 -> 互斥量实现原理探究 3 -> 可重入VS线程安全 3.1 -> 概念 3.2 -> 常见的线程不安全的情况 3.3 -> 常见的…