《深入理解计算机系统》(2):虚拟内存

虚拟内存是一种对主存的抽象概念。
(1)将主存看作一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式高效地使用内存
(2)为每个进程提供一致的地址空间,从而简化内存管理。
(3)保护每个进程的地址空间不被其它进程破坏。
在这里插入图片描述

1、物理寻址
计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组。每字节都有一个唯一的物理地址。第一个字节的地址为0,接下来的字节地址为1,再下一个为2,依此类推CPU访问内存的最自然的方式就是使用物理地址。这种方式称为物理寻址。
在这里插入图片描述

早期的PC使用物理寻址,而且诸如数字信号处理器、嵌人式微控制器以及Cray超级计算机这样的系统仍然继续使用这种寻址方式。然而,现代处理器使用的是一种称为虚拟寻址(virtual addressing)的寻址形式。

2、虚拟寻址
虚拟内存地址是指令用到的内存地址;物理内存地址是实际在内存硬件中的空间地址。
CPU通过生成一个虚拟地址来访问主存,这个虚拟地址在被送到内存之前先转换成适当的物理地址。将一个虚拟地址转换为物理地址的任务叫做地址翻译。就像异常处理一样,地址翻译需要CPU硬件和操作系统之间的紧密合作。CPU芯片上叫做内存管理单元(Memory Management Unit,MMU)的专用硬件,利用**存放在主存中的查询表(页表)**来动态翻译虚拟地址,该表的内容由操作系统管理。
在这里插入图片描述

3、虚拟页和物理页
虚拟内存被组织成一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。每字节都有一个唯一的虚拟地址,作为数组索引。磁盘上数组的内容被缓存在主存中。
虚拟内存被分割为虚拟页VP,物理内存被分割为物理页PP。

在任意时刻,虚拟页面的集合都分为三个不相交的子集:

  • 未分配的:系统还未分配(或者创建)的页。未分配的块没有任何数据和它们相关联,因此也就不占用任何磁盘空间。
  • 已分配但缓存的:当前已缓存在物理内存中的已分配页,在主存中。
  • 已分配但未缓存的:未缓存在物理内存中的已分配页,在磁盘中。

4、页表
同任何缓存一样,虚拟内存系统必须有某种方法来判定一个虚拟页是否缓存在DRAM中的某个地方。如果是,系统还必须确定这个虚拟页存放在哪个物理页中。如果不命中,系统必须判断这个虚拟页存放在磁盘的哪个位置,在物理内存中选择一个牺牲页,并将虚拟页从磁盘复制到DRAM中,替换这个牺牲页。

这些功能是由软硬件联合提供的,包括操作系统软件、MMU(内存管理单元)中的地址翻译硬件和一个存放在物理内存中叫做页表(page table)的数据结构,页表将虚拟页映射到物理页。每次地址翻译硬件将一个虚拟地址转换为物理地址时,都会读取页表。操作系统负责维护页表的内容,以及在磁盘与DRAM之间来回传送页。

页表就是一个页表条目(Page Table Entry,PTE)的数组。虚拟地址空间中的每个页在页表中一个固定偏移量处都有一个PTE。
在这里插入图片描述
PTE中的有效位为0表示未分配,地址字段为null;或者已经分配了但是没有缓存到物理内存中,地址字段指向磁盘地址;为1时表示已经缓存到物理内存中,地址字段指向物理页号。

页命中:
CPU读取包含在虚拟内存中某虚拟页的一个字,该虚拟页已经缓存在主存中,使用PTE中的物理内存地址构造出这个字的物理地址。

缺页:
物理内存不命中即缺页。地址翻译硬件从内存中读取PTE,从有效位推断出该虚拟页未被缓存(未分配的PTE没有联系任何数据,不会被读取),并且触发一个缺页异常。缺页异常调用内核中的处理程序,该程序
(1)判断虚拟地址是否合法,是否是某个区域结构定义的区域,访问空白区域会触发段错误。
(2)内存访问是否合法,是否有读取该地址空间的权限。
(3)对合法的虚拟地址进行合法的操作:选择物理内存中的一个物理页作为牺牲页,从磁盘上用虚拟页的副本取代该牺牲页。程序返回之后CPU重新启动导致缺页的指令,正常读取不会产生异常。

页面分配:
调用malloc的结果,就是在磁盘上创建空间(创建新的虚拟页)并更新某个未分配的页表条目PTE,使它指向磁盘上这个新创建的页面。

5、内存映射
linux将一个虚拟内存区域和一个磁盘上的对象关联起来,初始化这个虚拟内存区域的内容,这个过程称为内存映射,映射为文件系统中的普通文件或者内核创建的匿名文件。
一个区域可以映射到一个普通磁盘文件的连续部分,例如一个可执行目标文件。文件区被分为页大小的片,每一片包含一个虚拟页面的初始内容。

共享对象和私有对象:
一个对象可以被映射到虚拟内存的一个区域,要么作为共享对象,要么作为私有对象。
共享对象:如果一个进程将一个共享对象映射到它的虚拟地址空间的一个区域内,那么这个进程对这个区域的任何写操作,对于那些也把这个共享对象映射到它们虚拟内存的其他进程而言,也是可见的。而且,这些变化也会反映在磁盘上的原始对象中。

私有对象:另一方面,对于一个映射到私有对象的区域做的改变,对于其他进程来说是不可见的,并且进程对这个区域所做的任何写操作都不会反映在磁盘上的对象中。

一个映射到共享对象的虚拟内存区域叫做共享区城。类似地,也有私有区城。

写时复制:
私有对象使用写时复制的技术映射到虚拟内存中。一个私有对象开始生命周期的方式和共享对象一样,在物理内存中只保存私有对象的一份副本。当一个进程试图写私有区域的某个界面,这个写操作会触发一个保护故障。处理程序会在物理内存中创建这个页面的一个新副本,并更新页表条目。程序返回时CPU重新执行写操作即正常执行。

fork函数:
用于创建一个进程,所创建的进程复制父进程的代码段/数据段/BSS段/堆/栈等所有用户空间信息;在内核中操作系统重新为其申请了一个PCB,并使用父进程的PCB进行初始化;

当fork函数被当前进程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID。为了给这个新进程创建虚拟内存,它创建了当前进程的mm_struct、区域结构和页表的原样副本。它将两个进程中的每个页面都标记为只读,并将两个进程中的每个区域结构都标记为私有的写时复制。

当 fork在新进程中返回时,新进程现在的虚拟内存刚好和调用fork时存在的虚拟内存相同。当这两个进程中的任一个后来进行写操作时,写时复制机制就会创建新页面,因此,也就为每个进程保持了私有地址空间的抽象概念。

execve函数:
在当前进程中加载并运行包含在可执行目标文件中的程序,用该程序替代当前程序。
(1)删除已存在的用户区域
(2)映射私有区域
(3)映射共享区域
(4)设置程序计数器

mmap函数:
要求内核创建一个新的虚拟内存区域,并将指定对象的一个连续的片映射到这个新的区域。munmap用来删除虚拟内存区域。

6、动态内存分配
运行时需要额外虚拟内存时,用动态内存分配器更加方便,移植性更好。动态内存分配器维护堆,将堆视为一组不同大小的块的集合来维护。每个块就是一个连续的虚拟内存片,要么是已分配的,要么是空闲的。

C标准库提供一个称为malloc程序包的显式分配器,程序通过调用malloc函数来从堆中分配块。
动态内存分配器,如malloc,可以通过使用mmap和munmap函数,显式地分配和释放堆内存。

内存碎片:
造成堆利用率很低的主要原因是一种称为碎片(fragmentation)的现象,当虽然有未使用的内存但不能用来满足分配请求时,就发生这种现象。有两种形式的碎片:内部碎片(internal fragmentation)和外部碎片(external fragmentation)。

内部碎片是在一个已分配块比有效载荷大时发生的。很多原因都可能造成这个问题。例如,一个分配器的实现可能对已分配块强加一个最小的大小值,而这个大小要比某个请求的有效载荷大。或者分配器可能增加块大小以满足对齐约束条件。

内部碎片的量化是简单明了的。它就是已分配块大小和它们的有效载荷大小之差的和。因此,在任意时刻,内部碎片的数量只取决于以前请求的模式和分配器的实现方式。

外部碎片是当空闲内存合计起来足够满足一个分配请求,但是没有一个单独的空闲块足够大可以来处理这个请求时发生的。那么如果不向内核请求额外的虚拟内存就无法满足这个请求,即使在堆中仍然有足够多空闲的字。问题的产生是由于这些空闲字是分在多个空闲块中的。

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

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

相关文章

GitHub要求开启2FA,否则不让用了。

背景 其实大概在一个多月前,在 GitHub 网页端以及邮箱里都被提示:要求开启 2FA ,即双因子认证;但是当时由于拖延症和侥幸心理作祟,直接忽略了相关信息,毕竟“又不是不能用”。。 只到今天发现 GitHub 直接…

Linux软硬链接和动静态库

本文已收录至《Linux知识与编程》专栏! 作者:ARMCSKGT 演示环境:CentOS 7 软硬链接和动静态库 前言正文软硬链接原理使用 文件时间动静态库库介绍静态库静态库制作静态库的使用关于静态链接 动态库动态库制作动态库的使用关于动态链接 补充 最…

Java练习题-用冒泡排序法实现数组排序

✅作者简介:CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1🏆 📃个人主页:hacker707的csdn博客 🔥系列专栏:Java练习题 💬个人格言:不断的翻越一座又…

Computer Architecture Subtitle:Engineering And Technology

原文链接:https://www.cs.umd.edu/~meesh/411/CA-online/index.html

基于Springboot实现疫情网课管理系统项目【项目源码+论文说明】

基于Springboot实现疫情网课管理系统演示 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于疫情网课管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了疫情…

Windows11 安全中心页面不可用问题(无法打开病毒和威胁防护)解决方案汇总(图文介绍版)

本文目录 Windows版本与报错信息问题详细图片: 解决方案:方案一、管理员权限(若你确定你的电脑只有你一个账户,则此教程无效,若你也不清楚,请阅读后再做打算)方案二、修改注册表(常用方案)方案三、进入开发…

leetcode:2427. 公因子的数目(python3解法)

难度:简单 给你两个正整数 a 和 b ,返回 a 和 b 的 公 因子的数目。 如果 x 可以同时整除 a 和 b ,则认为 x 是 a 和 b 的一个 公因子 。 示例 1: 输入:a 12, b 6 输出:4 解释:12 和 6 的公因…

Meta分析的流程及方法

Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…

linux日志审计常用命令

文章目录 cut参数指定范围命令 awk参数内置变量命令 wc参数命令 uniq参数命令 sort参数命令 head参数 cut 参数 选项含义-b仅显示行中指定直接范围的内容-c仅显示行中指定范围的字符-d指定分割符, 默认为“TAB”制表符-f显示指定字段的内容-n与“-b”连用&#xf…

Prometheus普罗米修斯

什么是Prometheus 官网:Overview | Prometheus 是一个开源的系统监控和警报工具,多数Prometheus组件是Go语言写的 为用户提供可视化仪表板、警报、告警等功能,以帮助用户快速定位和解决问题 现在已经成为一个独立于企业级的开源项目和一个…

供水管网监测系统

随着城市人口的不断增长和经济的快速发展,供水管网的安全和可靠性变得尤为重要。在过去,供水管网的监测往往是依靠人工巡查,这种方式不仅费时费力,而且容易出现疏漏和盲区。然而,随着科技的进步,供水管网监…

大数据集群(Hadoop生态)安装部署

目录 1. 简介 2. 前置要求 3. Hadoop集群角色 4. 角色和节点分配 5. 调整虚拟机内存 6. Zookeeper集群部署 7. Hadoop集群部署 7.1 下载Hadoop安装包、解压、配置软链接 7.2 修改配置文件:hadoop-env.sh 7.3 修改配置文件:core-site…

Vue3目录结构与Yarn.lock 的版本锁定

Vue目录结构与Yarn.lock 的版本锁定 一、Vue3.0目录结构图总览 举个例子看vue的目录,一开始不知道该目录是什么意思目录里各个文件包里安放有什么,程序员在哪里操作该如何操作。 下图目录看Vue新项目 VS Code 打开文件包后出现一列目录 二、目录结构 1…

宝塔面板二次元透明主题美化模板

看惯了宝塔面板默认风格模板,我们可以试试自己美化修改,我的站长站知道一款非常漂亮的宝塔面板二次元透明主题美化模板,美不美大家看下图,分享给大家。 下载:飞猫盘|文件加速传输工具|云盘&…

Vulnhub系列靶机-The Planets Earth

文章目录 Vulnhub系列靶机-The Planets: Earth1. 信息收集1.1 主机扫描1.2 端口扫描1.3 目录爆破 2. 漏洞探测2.1 XOR解密2.2 解码 3. 漏洞利用3.1 反弹Shell 4. 权限提升4.1 NC文件传输 Netcat(nc)文件传输 Vulnhub系列靶机-The Planets: Earth 1. 信息…

软件工程师都应该知道的10个定律

一、海勒姆法则 内容 当一个 API 有足够多的用户,你在契约中承诺了什么并不重要:系统中所有看得见的行为都会有某个人依赖…… 案例 现在有两个系统A和B,B的一个接口返回一个列表。A系统的开发人员发现返回的列表都是按照ID正向排序的。本…

Flink实现kafka到kafka、kafka到doris的精准一次消费

1 流程图 2 Flink来源表建模 --来源-城市topic CREATE TABLE NJ_QL_JC_SSJC_SOURCE ( record string ) WITH (connector = kafka,topic = QL_JC_SSJC,properties.bootstrap.servers = 172.*.*.*:9092,properties.group.id = QL_JC_SSJC_NJ_QL_JC_SSJC_SOURCE,scan.startup.mo…

基于Springboot实现疫情网课管理系统项目【项目源码+论文说明】分享

基于Springboot实现疫情网课管理系统演示 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于疫情网课管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了疫情…

学习开发一个RISC-V上的操作系统(汪辰老师) — unrecognized opcode `csrr t0,mhartid‘报错问题

前言 (1)此系列文章是跟着汪辰老师的RISC-V课程所记录的学习笔记。 (2)该课程相关代码gitee链接; (3)PLCT实验室实习生长期招聘:招聘信息链接 正文 (1)在跟着…