虚拟内存技术原理解析
虚拟内存技术原理解析
1. 它将主存看成是一个存储在磁盘空间上的地址空间的高速缓存,主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据。
2. 它为进程提供了一致的地址空间,简化了内存管理。
3. 它保护了每个进程的地址空间不被其他进程破坏。
Process
1. 对cpu的分时使用
2. 每个进程都有自己的独立的虚拟内存空间。(虚拟内存的概念)
下图为如何将Process中的地址映射到物理内存。
mapping模块专门用于地址映射(将虚拟地址转换成物理地址),process无需关心具体到怎么取数据,可参考下图中的Indirection介绍。
现代操作系统的虚拟内存包括物理内存和磁盘存储空间。
直接寻址和间接寻址
在解释间接寻址和直接寻址前引入一个更抽象的概念,在计算机系统的很多方面都有使用(DNS),“Indirection”
无虚拟内存CPU寻址
计算机的主存可以看做是一个由 M 个连续的字节大小的单元组成的数组。每个字节都有一个唯一的物理地址(Physical Address,PA)。第一个字节的地址为 0,接下来的地址为 1,以此类推。CPU 访问内存的最简单的方式是使用物理寻址(physical addressing)。
虚拟内存操作系统CPU寻址
这里的MMU是一个很复杂的地址管理器(Memory ManagerMent Unit),将虚拟地址转换成物理地址。这里的MainMeMory包括内存空间和磁盘空间。
现代操作系统内存结构
原理解析
Q1: 为什么需要L1 cache和L2 cache
- cache 构造是SRAM,而主内存构造是DRAM,在读取速度上SRAM要远远快于DRAM(x10)。(SRAM/DRAM区别后文会讲解)
- cache的单位存储空间的价格要远远高于主内存
- CACHE,是一种特殊的内存。因为主内存速度不够快,用少量的特别快的但特别昂贵的内存来做缓存加速。就是cache。
- 缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。通过这种方式来加速cpu的工作。
Q2: 虚拟地址(VA)如何转换成物理地址(PA)空间
虚拟内存的存储单元为page(一般为4~8Kb)
同任何缓存一样,虚拟内存系统必须有某种方法来判定一个虚拟也是否缓存在 DRAM 的某个地方。如果命中缓存,那么虚拟内存系统还必须确认这个虚拟页存在哪个物理页中。如果没有命中缓存,那么虚拟内存系统必须判断虚拟页存放在磁盘的哪个位置,在物理内存中选择一个牺牲页,并将虚拟页从磁盘复制到 DRAM,替换这个牺牲页。
这些功能由软硬件联合提供,包括操作系统软件,MMU 中的地址翻译硬件和一个存放在物理内存中叫页表(page table)的数据结构,页表将虚拟页映射到物理页。每次地址翻译硬件将一个虚拟地址转换成物理地址时都会读取页表。
上图展示了一个页表的基本结构,页表就是一个页表条目(Page Table Entry,PTE)的数组。虚拟地址空间中的每个页在页表中都有一个 PTE。在这里我们假设每个 PTE 是由一个有效位(Valid bit)和一个 n 位地址字段组成的。有效位表明了该虚拟页当前是否被缓存在 DRAM 中。如果有效位为 1,那么地址字段就表示 DRAM 中相应的物理页的起始位置,这个物理页缓存了该虚拟页。如果有效位为 0,那么一个 null 地址表示这个虚拟页还未被分配,否则对应的这个地址就指向该虚拟页在磁盘上的起始位置。
上图所示中一共有 8 个虚拟页和 4 个物理页的页表,4 个虚拟页 VP1, VP2, VP4, VP7 当前被缓存在 DRAM 中,VP0 和 VP5 还未被分配,而剩下的 VP3 和 VP6 已经被分配了,但是当前未被缓存。
- 假如读取页表中的第三页时,因为页表中指向物理内存,所以可以直接读取。
- 假如读取页表中的第四页时,由于该页数据在磁盘中,所以产生缺页中断,由缺页中断程序负责将vp3中的数据复制到物理内存中,假如是pp3。(将不经常使用的页内容替换为vp3数据)。然后修改页表中的数据(这时页表中原本指向pp3的数据指向了磁盘空间),这样就能成功的加载数据了。
Q3: 使用磁盘内存作为内存映射一部分的优缺点:
1. 使用虚拟内存最大的优点就是扩充物理内存。
(磁盘速度是内存速度的1/10000 级别、内存空间有限而磁盘空间很大,x100级别)
2. 它为进程提供了一致的地址空间,简化了内存管理。
3. 它保护了每个进程的地址空间不被其他进程破坏。
带来的问题:大量的缺页中断会影响性能
当我们了解了虚拟内存的运作机制之后,是不是觉得虚拟内存的效率会很低呢?因为页面没有命中的代价非常大。是不是担心虚拟内存会影响程序的性能呢?其实虚拟内存运作的非常好。它充分利用了局部性( locality )的原理。
在程序整个运作过程中,程序引用的不同页面的总数可能超出了物理内存的总大小,但是局部性原则可以保证在任意时刻,程序将趋向于在一个较小的活动页面(active page)集合上工作,这个集合被称作工作集(working set)或者常驻集合(resident set)。在程序初始开销之后也就是将工作集页面调入主存,接下来对这个工作集的访问会产生命中,这样就不会产生额外的磁盘消耗。
如果程序有良好的时间局部性,那么虚拟内存将工作的非常好。如果程序没有良好的时间局部性也就是工作集的大小超出了主存的大小,那么程序将会进入一个称作 抖动(thrashing)的状态,这个时候页面将不断地换进换出,程序会出现性能问题。
Q4: 进程地址空间为什么能够相互独立与共享
上图可以看出每个进程有连续的虚拟内存地址,但是对于的物理内存并不是连续的。
内存独立: 我们只需要保证,物理页不能被两个进程同时使用
内存共享: 部分物理页可以被多个进程访问,同时可以分配读写权限。
ROM/RAM
1. ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写。
2. ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是在掉电之后就丢失数据,典型的RAM就是计算机的内存。
因为本片讨论的内存技术,所以这里重点介绍一下 SRAM和DRAM
SRAM
1. 利用寄存器来存储信息,所以一旦掉电,资料就会全部丢失.
2. 只要供电,它的资料就会一直存在,不需要动态刷新,所以叫静态随机存储器。
3. 造价高(用于Cache)
DRAM
1. 属于RAM,掉电后数据会丢失
2. 利用MOS管的栅电容上的电荷来存储信息,一旦掉电信息会全部的丢失,由于栅极会漏电,所以每隔一定的时间就需要一个刷新机构给这些栅电容补充电荷,并且每读出一次数据之后也需要补充电荷,这个就叫动态刷新,所以称其为动态随机存储器。
2. 一般用于内存
参考:
ram/rom
vitual memory
视频课程已分享到文档云
链接:https://pan.baidu.com/s/1LnCDNJUoNck_qZTp7_LmGA
提取码:mc21
原文地址:https://www.cnblogs.com/NeilZhang/p/11521856.html
- 左手用R右手Python系列之——noSQL基础与mongodb入门
- 左手用R右手Python系列之——数据框与apply向量运算
- 左手用R右手Python系列之——迭代器与迭代对象
- 【关关的刷题日记61】Leetcode 102. Binary Tree Level Order Traversal
- 【关关的刷题日记62】Leetcode 104. Maximum Depth of Binary Tree
- DataAnnotations - InverseProperty Attribute:
- 【关关的刷题日记63】Leetcode 111 Minimum Depth of Binary Tree
- Configure Many-to-Many relationship:
- 【关关的刷题日记64】Leetcode 110 Balanced Binary Tree
- 左手用R右手Python系列之——json序列化与反序列化
- 【干货】GAN调研:多极扩展(跨域和条件的GAN扩展模型调研)
- 【干货】TensorFlow实战——图像分类神经网络模型
- HTML5手机APP开发入(5)
- 这种自带黑科技的R包,请给我来一打
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【python-leetcode23-多路归并】合并k个排序链表
- 实战django(二)--登录实现记住我
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.gong.mybatis.da
- 【python-leetcode378-二分查找】有序矩阵中的第k小元素
- 使用cookie来记录用户登录次数,为何次数不更新
- (二)golang--windows下vscode的安装以及go环境的配置
- mybatis文件映射之使用#取值时的一些规则
- 【论文笔记】Improved Residual Networks for Image and Video Recognition(ResNet新变体:IResNet)
- SQL语句在MYSQL中的运行过程和各个组件的介绍
- (五)golang--常用的一些玩意
- 关于MYSQL 的日志系统
- (六)golang--变量
- springmvc之文件上传
- (七)golang--变量之基本数据类型(看这篇就够了)
- Mybatis学习笔记(五)Mybatis中已经显示数据已修改但数据库中记录未更新问题