《深入浅出计算机组成原理》学习笔记 Day4

1. 虚拟内存

在链接器把多个文件合并成一个最终可执行文件之后,当要运行这些可执行文件的时候,其实是通过一个装载器来解析 ELF 或者 PE 格式的可执行文件。

装载器会把对应的指令和数据加载到内存里面来,让 CPU 去执行。

一个可行的装载器需要满足两个要求:

  1. 可执行程序加载后占用的内存空间应当连续。执行指令的时候,程序计数器是顺序地一条一条指令执行下去。
  2. 能够同时加载多个程序,并且不能让程序自己规定在内存中加载的位置。现在的计算机会同时运行很多个程序,一个程序想要的内存地址可能已经被其他加载了的程序占用了。

虚拟内存就是一个很好的方法。
我们可以在内存里面找到一段连续的内存空间,然后分配给装载的程序,
接下来把这段连续的内存空间地址和程序指定的内存地址做一个映射。

其中,程序指定的内存地址叫做虚拟内存地址(Virtual Memory Address),实际在内存硬件的空间地址叫做物理内存地址(Physical Memory Address)。

对于每个程序来说,它看到的都是同样的内存地址——虚拟内存地址。我们只需要维护一个虚拟内存到物理内存的映射表,这样实际程序执行的时候,会通过虚拟内存地址找到对应的物理内存地址,然后执行。

2. 内存分段

这种找出一段连续的物理内存和虚拟内存地址进行映射的方法,叫分段(Segmentation)。段就是指系统分配出来的那个连续的内存空间。

有了分段,程序本省不用关心具体的物理内存地址的问题。但分段也有一个不足——内存碎片(Memory Fragmentation)。说白了,就是内存中连续的、足够大的空间少,都是一个隔一个的空间。

可以通过内存交换(Memory Swapping)来解决。A程序需要一个很大内存空间,此时B程序在运行,B的物理内存空间大小 + 与B相邻的最大的空闲内存正好能满足A。于是我们就将B的内存写到硬盘上,然后再另寻一块满足B的内存空间,将从硬盘读到内存中的这块空间。于是A、B都能得到满足。

Linux操作系统就是通过 swap 硬盘分区来实现内存交换。

3. 内存分页

既然问题出在内存碎片和内存交换的空间太大上,那么解决问题的办法就是,少出现一些内存碎片。另外,当需要进行内存交换的时候,让需要交换写入或者从磁盘装载的数据更少一点,这样就可以解决这个问题。这个办法,在现在计算机的内存管理里面,就叫作内存分页(Paging)。

分页是把整个物理内存空间切成一段段固定尺寸的大小。对应的程序所需要占用的虚拟内存空间,也会同样切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,称为(Page)。

从虚拟内存到物理内存的映射,不再是拿整段连续的内存的物理地址,而是按照一个一个页来的。页的尺寸一般远远小于整个程序的大小。在 Linux 下,通常只设置成 4KB。

由于内存空间都是预先划分好的,也就没有了不能使用的碎片,而只有被释放出来的很多 4KB 的页。即使内存空间不够,需要让现有的、正在运行的其他程序,通过内存交换释放出一些内存的页出来,一次性写入磁盘的也只有少数的一个页或者几个页,不会花太多时间,让整个机器被内存交换的过程给卡住。

更进一步地,分页的方式使得我们在加载程序的时候,不再需要一次性都把程序加载到物理内存中。完全可以在进行虚拟内存和物理内存的页之间的映射之后,并不真的把页加载到物理内存里,而是只在程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存里面去。

当要读取特定的页,却发现数据并没有加载到物理内存里的时候,就会触发一个来自于 CPU 的缺页错误(Page Fault)。操作系统会捕捉到这个错误,然后将对应的页,从存放在硬盘上的虚拟内存里读取出来,加载到物理内存里。这种方式,使得可以运行那些远大于我们实际物理内存的程序。同时,这样一来,任何程序都不需要一次性加载完所有指令和数据,只需要加载当前需要用到就行了。这种方法也称为写时复制(Copy On Write)。

4. 总结

通过虚拟内存、内存交换和内存分页这三个技术的组合,最终得到了一个让程序不再需要考虑实际的物理内存地址、大小和当前分配空间的解决方案。

这些技术和方法,对于我们程序的编写、编译和链接过程都是透明的。任何一个程序,只需要把内存当成是一块完整且连续的空间来使用。

这也是在计算机的软硬件开发中常用的一种方法——加入一个间接层。

参考

极客时间《深入浅出计算机组成原理》:http://gk.link/a/11UMi

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Balaaam

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值