内存管理之虚拟内存

2023-09-21 16:40:35

本篇遵循内存管理->地址空间->虚拟内存的顺序描述了内存管理、地址空间与虚拟内存见的递进关系,较为详细的介绍了作为在校大学生对于虚拟内存的理解。

内存管理

引入

  • RAM(内存)是计算机中非常重要的资源,由于造价的昂贵,我们家用的计算机一般是8/16G。对于如此紧俏的资源我们当然需要对它好好管理,尽力做到不浪费,高效压榨它的每一分资源。因此,我们需要内存管理。
  • 在计算机中,有着高达几TB的低速、廉价、持久化存储的磁盘,也有着GB单位的速度与价格适中的具有亦失性的内存,还有昂贵的高速缓存,CPU,种种硬件叠加在一起,形成分层存储器体系
  • 在操作系统中,管理分层存储器体系的部分称为存储管理器。接下来我们来介绍存储管理器。

存储管理器的两种抽象

最简单的存储器抽象

  • 最简单就是没有存储器抽象。对于无存储器抽象的情况这里不做过多讨论,一般在嵌入式像门卡这种设备才会出现这种情况,因为门卡这样的设备只需要执行预定好的程序,不会发生冲突,程序要做的事情都是预先确定好的。
  • 我们这里只要清楚一点,即无存储管理器抽象的计算机上,程序都是直接操作物理内存地址的。而暴露物理地址给进程会有如下几个问题:
    • 用户程序可能会破坏操作系统,访问了不该访问的区域,比如无意间修改了系统的数据导致系统出错。
    • 无法同时运行多个程序,一个程序运行可能会覆盖另外一个程序的代码或数据。

地址空间

地址空间的引入
  • 为了解决无存储器抽象带来的两个问题,我们引入地址空间这个存储器抽象的概念,我们的主题虚拟内存就和地址空间有关。
  • 首先,无存储器抽象的两个问题主要就是一个问题,即用户程序随意寻址进行操作!这个问题拆分成子问题就是:解决保护和重定位!
    • 这里引入A、B进程
    • A 进程要想防止 B 进程修改 A 的代码或数据,我们就需要对 A 所用到的内存地址进行保护,防止 B 程序修改 A所用到的地址上的内容。
    • 但同时我们的 B 进程之所以会去修改,是因为 B 进程有指令执行,可能B进程的目的不是修改A的某个用到的地址所填的内容或数据,而只是想要执行CPU指令,如果光光进行保护而不重定向,B这个指令就没法儿执行,所以还需要对 B 指令索引的地址进行重定向到别的位置,来实现 B 进程的指令。
  • 此时我们就可以提出地址空间的概念了:地址空间是一个进程可用于寻址内存的一套地址集合。它保证了每个进程都有自己独立的地址空间。
怎么做到每个进程都有自己独立的地址空间的
  • 答案就是我们今天的主题:虚拟内存

虚拟内存

阅读完前面的内容,对于虚拟内存的由来大致有了一个了解,接下来介绍虚拟内存的原理以及相关周边知识。

页、页表、页表项、页框

首先我们了解一下这四个概念


  • 每个程序拥有自己的地址空间,这个空间被分割成多个块,每一块称作一。每一页有连续的地址范围。一般在32为地址空间中是4KB。
  • 页框
    与虚拟地址相映射的实际的物理地址
  • 页表
    类似一个数组,保存了大量的页表项。用页号作为页表的索引
  • 页表项
    存储着进程所使用到的虚拟地址空间与实际物理地址的映射关系,同时还保存了该地址是否存在,权限是读、写还是执行,修改位等,都是使用比特位的方式进行标识。(为锻炼广大猿友的搜索能力,有兴趣的还请自行搜索了解页表项中的内容)
    在这里插入图片描述

虚拟内存与分页的基本思想

  • 虚拟内存的基本思想是:
    这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立刻执行必要的映射。当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令(缺页中断)。
    什么意思呢?举个例子:
    • windows上的游戏3A大作,动辄上百个G的资源文件下下来,那么多的代码和数据资源,我们的电脑也就16G的内存,如果全部加载到内存中,依据我们电脑上显示的实际物理内存,游戏怎么可能跑的起来呢?有了虚拟内存,我们计算机只从磁盘加载部分当前和最近一部分时间会用到的数据到内存中,当需要磁盘中其他部分代码和数据时我们再动态的加载那部分代码和数据。我们打游戏时或处理使用一些大型软件时,电脑会发热,本质也就是因为硬件在不断的进行 IO 操作,摩擦生热。
      下面对提到的页进行一个介绍
  • 分页的基本思想
    • 如果没有虚拟内存,那么操作系统会将CPU会将指令直接传递到内存总线来获取物理地址。
      而使用了虚拟内存管理策略,OS将会把CPU指令所需的内存地址传输给另一个硬件设备(CPU的一部分):内存管理单元(Memory Management Unit->MMU)。MMU会将虚拟地址映射成物理内存地址,最后返还给CPU。
      来自现代操作系统3-8,3-9

具体是怎么做的呢?
- 虚拟地址一共两部分组成,虚拟页号(高位)以及偏移量(低位)。页号作为页表的索引,根据页号在页表中找到对应的页表项,通过页表项中存的页框号拼接到偏移量的高位以替代虚拟页号,MMU拿到该拼接而成的地址后,判断是否满足保护位的要求,即能不能写或读或执行,确认没有问题后将其通过地址总线送往内存,进行寻址找到对应数据进行读写操作。如果在页表项中没有找到对应的映射,则触发缺页中断
下面介绍缺页中断

缺页中断之页面置换

  • 首先,缺页中断指的就是在虚拟地址所对应的页表项中没有找到对应的物理地址映射时,称为缺页。
  • 此时CPU陷入内核态,OS找到一个已经存在映射关系的并且很少使用的页框,将其内容写回磁盘,内存中不再保留该页框存储的数据,随后将触发缺页中断的指令对应要进行的操作读到刚才找到的页框中,那么此时该页框就有了新的数据,该页表项中就写入了刚才找到的页框地址。新的映射关系就这样建立了。
  • 那么,页面置换就是上面讲到的内容,缺页中断中的一个策略,也是动态加载内存的关键。
  • 当发生缺页中断时,操作系统必须在内存中选择一个页面将其换出内存,以便为即将调入的页面腾出空间。如果要换出的页面在内存驻留期间已经被修改过,就必须把它写回磁盘以更新该页面在磁盘上的副本,如果该页面没有被修改过,那么它在磁盘上的副本已经是最新的,不需要回写。直接用调入的页面覆盖被淘汰的页面就可以了。

分页系统的两个问题

  1. 虚拟地址到物理地址的映射性能问题
  2. 页表太大的问题
性能问题

想要知道关于性能问题的原理可以自行看现代操作系统内存管理一章,这里只对解决方案进行介绍。

  • 要解决每次访问内存都要从虚拟地址映射的物理地址的速度问题,TLB(转换检测缓冲区/快表)问世。
  • 其实该技术就是基于程序届的二八原则,热点总是少数的,被经常访问的页面总是那么一小撮,绝大部分很少被用到,那么基于该原则,TLB被设计出来。
  • 其工作原理就是开一块儿小空间,加载少量页表项,将虚拟地址送到MMU,MMU先去TLB里找虚拟地址对应的页表项,如果找到了就直接通过内存总线传输物理地址去内存,没找到再去页表里找。
页表太大
  • 在32位的地址空间中,假设1个page=4kb,那么一共就会有2^32/4kb=100万个页,也即100万个页表项。通常一个页表项为4字节,那1个进程就需要1个G的内存来存页表,这有点不可思议,这里指的可是真是的物理内存需要1个G。
    所以,一级页表在现代计算机中是活不下去的。

  • 于是,产生出了多级页表,这里以2级页表为例

    • 32位地址空间,把它分成10位的1级页目录表项,10位页表项和12位偏移量
    • 在这里插入图片描述
  • 我们一级页表一共有1024个表项,对应10位的1级页表,2级页表每个也有1024个表项,对应PT2。

  • 当我们CPU发出指令需要某一块儿地址时,MMU来一级页表寻找,如果一级页表对应的虚拟地址没有映射二级页表,则触发缺页中断,加载对应的2级页表,然后再通过加载的2级页表找到对应的映射,继而执行CPU指令。

  • 所以从这里我们可以看出,多级页表有1个功能叫做动态加载,即我需要你的时候再加载这块空间的页表进来,而不用一次性维护上百万的页表项。

更多推荐

《Linux操作系统实战》| 面试了两个实习生,Linux 基本命令都不会(一)

😄作者简介:小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊座右铭:不想当开发的测试,不是一个好测试✌️。如果感觉博主的文章还不错的话,还请点赞、收藏哦!👍文章目录一、前言二、初识LinuxLinux诞生Linux

数据结构——散列函数、散列表

文章目录前言一、散列表的基本概念二、散列函数的构造方法三、处理冲突的方法1.开放定址法:2.拉链法四、散列查找及性能分析总结前言散列表的基本概念散列函数的构造方法处理冲突的方法散列查找及性能分析提示:以下是本篇文章正文内容,下面案例可供参考一、散列表的基本概念概念:之前的算法建立在“比较”基础上,效率取决于比较次数散列

武汉凯迪正大—继电保护测试仪

一、凯迪正大微机继电保护测试仪产品概述KDJB系列微机继电保护校验仪是在参照电力部颁发的《微机型继电保护试验装置技术条件(讨论稿)》的基础上,听取用户意见,总结目前国内同类产品优缺点,充分使用现代的微电子技术和器件实现的一种小型化微机继电保护测试仪。它采用单机独立运行,亦可联接笔记本电脑运行。主机内置新一代高速数字信号

【zookeeper】基于Linux环境安装zookeeper集群

前提,需要有几台linux机器,我们可以准备好诸如finalshell来连接linux并且上传文件;其次Linux需要安装上ssh,并且在/etc/hosts文件中写好其他几台机器的名字和Ip127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.loca

ChatGLM 大模型外挂(向量)知识库

前言如果我们想往大模型里边注入知识,最先能想到的就是对大模型进行微调。笔者曾实验过,只用几十万量级的数据对大模型进行微调并不能很好的将额外知识注入大模型,笔者在算力这方面囊中羞涩,只有4块卡,这几十万量级的数据训练6B的模型都要训练好几天。。。如果不微调的话,其实还是可以利用外挂数据库的方式让大模型利用额外的知识的,比

Python案例|使用卷积网络对星系图片进行分类

星系动物园(galaxyzoo)是由牛津大学等研究机构组织并邀请公众协助的志愿者科学计划,目的是为超过100万个星系图像进行分类。这是天文学中一次规模浩大的公众星空普查活动,大众参与热情高涨,在近十万名志愿者的积极参与下,只用了175天就完成了第一阶段的星系动物园项目:对95万个星系进行了分类,而且平均每个星系被分类了

Haproxy集群调度器与部署

一、Haproxy介绍:1.Haproxy应用分析:LVS在企业中康复在能力很强,但存在不足:LVS不支持正则处理,不能实现动静分离对于大型网站LVS的事实配置较为复杂,维护成本相对较Haproxy是一款可以供高可用性、负载均衡和基于TCP和HTTP应用的代理软件非常适用于并发大(并发达1w以上)web站点,可保持站点

高阶数据结构(2)-----红黑树(未完成)

一)红黑树的基本概念和基本性质:1)红黑树就是一种高度平衡的二叉搜索树,但是在每一个节点上面都增加了一个存储位来表示结点的颜色,可以是红色或者是黑色,通过对任何一条从根节点到叶子节点上面的路径各个节点着色方式的限制,红黑树会自动确保没有一条路经会比其他路径的长度高出两倍,而是接近平衡的2)红黑树最长路径是最短路径的两倍

vue3 effect.spec

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录原型观察的对象的变更会同步到原始对象重复观察相同的原始对象直接返回相同的proxy对象不会污染原始对象通过toRawapi可以返回被观察对象的原始对象shallowReactive结语定义一个对象origina

JavaScript的三大组成部分是什么?JavaScript的核心组成部分解析:语法、BOM和DOM

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

Nex.js Web 应用程序 SSG 与 SSR——选择正确的渲染方法

Next.js,一个流行的React框架,改变了开发人员构建现代Web应用程序的方式。它提供了强大的功能,例如服务器端渲染(SSR)和静态站点生成(SSG),可优化应用程序的性能和用户体验。在这篇博文中,我们将探讨SSG和SSR之间的主要区别、它们的优势、何时选择其中一种方法,以及如何使用AWSAmplify部署这两种

热文推荐