简单介绍虚拟内存

声明:以下内容为学习小林图解网络所做的简单笔记,更多详情请关注小林coding学习

为什么需要虚拟内存

为了让系统可以运行更多的进程,进程之间不能互相干扰,所以进程之间需要占用不同的物理内存,解决的办法就是给每个进程分配一套虚拟内存,虚拟内存通过cpu的内存管理单元映射到物理内存。

程序使用的内存地址叫做虚拟地址
实际存在硬件中的空间地址叫做物理地址

为了管理虚拟地址与物理地址之间的关系

主要有以下两种方式
内存分段和内存分页

  • 内存分段
    内存分段的虚拟地址主要由两部分组成:
    段选择因子和段内偏移量,段选择因子中记录了段号,通过段号可以找到段表,段表中记录了段基地址、段界限。段内偏移量是一个介于0和段界限之间的数值,通过段内偏移量+段基地址就可以找到物理地址了

优点:能产⽣连续的内存空间,使程序本身不需要关⼼具体的物理内存地址
缺点:1.第⼀个就是内存碎⽚的问题。
2.第⼆个就是内存交换的效率低的问题

外部内存碎⽚,也就是产⽣了多个不连续的⼩物理内存,导致新的程序⽆法被装载;
内部内存碎⽚,程序所有的内存都被装载到了物理内存,但是这个程序有部分的内存可能并不是很常使⽤,这也会导致内存的浪费;

  • 内存分页
    内存分页的虚拟地址由页号和页内偏移组成,根据页号在页表中找到虚拟地址对应的物理地址的基地址,通过页内偏移加上基地址就找到了物理地址

内存分页可以很好的解决内存分段出现的问题,分⻚是把整个虚拟和物理内存空间切成⼀段段固定尺⼨的⼤⼩。这样⼀个连续并且尺⼨固定的内存空间,我们叫⻚(Page)。在 Linux 下,每⼀⻚的⼤⼩为 4KB 。

通过页表来完成虚拟内存和物理内存的映射,页表是每个进程独有、存储在内存⾥的,通过内存管理单元 (MMU)完成将虚拟内存地址转换成物理地址的⼯作。

当进程访问的虚拟地址在⻚表中查不到时,系统会产⽣⼀个缺⻚异常,进⼊系统内核空间分配物理内存、更新进程⻚表,最后再返回⽤户空间,恢复进程的运⾏

分⻚是怎么解决分段的内存碎⽚、内存交换效率低的问题?

由于内存空间都是预先划分好的,程序在内存中按页存储,不会像分段那样产生非常小的内存间隙,分⻚的⽅式使得我们在加载程序的时候,不再需要⼀次性都把程序加载到物理内存中。我们完全可以在进⾏虚拟内存和物理内存的⻚之间的映射之后,并不真的把⻚加载到物理内存⾥,⽽是只有在程序运⾏中,需要⽤到对应虚拟内存⻚⾥⾯的指令和数据时,再加载到物理内存⾥⾯去。

多级页表

简单的分页会有空间上的缺陷,如果系统中运行的进程非常多,那就意味着页表占用的内存会很多。

简单的计算一下,在 32 位的环境下,虚拟地址空间共有 4GB,假设⼀个⻚的⼤⼩是 4KB(2^12),那么就需要⼤约 100 万
(2^20) 个⻚,每个「⻚表项」需要 4 个字节⼤⼩来存储,那么整个 4GB 空间的映射就需要有 4MB的内存来存储⻚表。
这 4MB ⼤⼩的⻚表,看起来也不是很⼤。但是要知道每个进程都是有⾃⼰的虚拟地址空间的,也就说都有⾃⼰的⻚表。
那么, 100 个进程的话,就需要 400MB 的内存来存储⻚表,这是⾮常⼤的内存了。

为了解决上述问题,引入了多级页表
比如说二级页表,将上述的100多万个页,先分成1024个一级页表,再将每个一级页表分成1024个页表项,形成二级页表。
如果某个⼀级⻚表的⻚表项没有被⽤到,也就不需要创建这个⻚表项对应的⼆级⻚表了,即可以在需要时才创建⼆级⻚表,实现节约内存的目的

那么为什么不分级的⻚表就做不到这样节约内存呢?

我们从⻚表的性质来看,保存在内存中的⻚表承担的职责是将虚拟地址翻译成物理地址。假如虚拟地址在⻚表中找不到对应的⻚表项,计算机系统就不能⼯作了。所以⻚表⼀定要覆盖全部虚拟地址空间,不分级的⻚表就需要有 100 多万个⻚表项来映射,⽽⼆级分⻚则只需要 1024 个⻚表项(此时⼀级⻚表覆盖到了全部虚拟地址空间,⼆级⻚表在需要时创建)。

引入多级页表带来的问题

虚拟地址到物理地址的映射多了几道转换的工序,也就是带来了时间上的开销,为了降低这种开销,引入了TLB(Translation Lookaside Buffer),或者称为⻚表缓存、快表等,将经常访问的页表项缓存在TLB中,有了 TLB 后,那么 CPU 在寻址时,会先查 TLB,如果没找到,才会继续查常规的⻚表。
TLB 的命中率其实是很⾼的,因为程序最常访问的⻚就那么⼏个。

段⻚式内存管理

内存分段和内存分⻚并不是对⽴的,它们是可以组合起来在同⼀个系统中使⽤的,那么组合起来后,通常称为段⻚式内存管理

段⻚式内存管理实现的⽅式:

  • 先将程序划分为多个有逻辑意义的段,也就是前⾯提到的分段机制
  • 接着再把每个段划分为多个⻚,也就是对分段划分出来的连续空间,再划分固定⼤⼩的⻚;

虚拟地址结构由段号、段内⻚号和⻚内位移三部分组成。
在这里插入图片描述

段⻚式地址变换中要得到物理地址须经过三次内存访问:
第⼀次访问段表,得到⻚表起始地址;
第⼆次访问⻚表,得到物理⻚号;
第三次将物理⻚号与⻚内偏移组合,得到物理地址。

可⽤软、硬件相结合的⽅法实现段⻚式地址变换,这样虽然增加了硬件成本和系统开销,但提⾼了内存的利⽤率

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值