0x103 虚拟内存
复习时思考
- 什么是虚拟内存
- 为什么使用虚拟内存
- 虚拟内存是如何实现的
什么是虚拟内存(Virtual Memory)?
虚拟内存可以让程序可以拥有超过系统物理内存大小的可用内存空间。
虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存的错觉(每个进程拥有一片连续完整的内存空间)
虚拟内存的重要意义是它定义了一个连续的虚拟地址空间,并且 把内存扩展到硬盘空间。
[!NOTE] 维基百科中有几句话是这样介绍虚拟内存的
虚拟内存 使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。From: https://zh.wikipedia.org/wiki/虚拟内存 214
CPU如何定位到数据在内存上的位置?虚拟地址空间?为什么需要虚拟地址空间?
如何定位
现代处理器使用的是一种称为 虚拟寻址(Virtual Addressing) 的寻址方式。使用虚拟寻址,CPU需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。
虚拟地址空间是什么?
虚拟地址空间是一个非常抽象的概念,先根据字面意思进行解释:
- 它可以用来加载程序数据(数据可能被加载到物理内存上,空间不够就加载到虚拟内存中)
- 它对应着一段连续的内存地址,起始位置为 0。
- 之所以说虚拟是因为这个起始的 0 地址是被虚拟出来的, 不是物理内存的 0 地址。
首先要分清“可以寻址”和“实际使用”的区别。
其实我们讲的每个进程都有4G虚拟地址空间,讲的都是“可以寻址”4G,意思是虚拟地址的0-3G对于一个进程的用户态和内核态来说是可以访问的,而3-4G是只有进程的内核态可以访问的。并不是说这个进程会用满这些空间。
32位系统的寻址空间是 4G ,64位系统的寻址空间是17179869184GB,约等于17179PB
其次,所谓“独立拥有的虚拟地址”是指对于每一个进程,都可以访问自己的0-4G的虚拟地址。虚拟地址是“虚拟”的,需要转化为“真实”的物理地址。
实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件。MMU 需要借助存放在内存中的页表来动态翻译虚拟地址,该页表由操作系统管理。
为什么需要虚拟地址空间?
- 连续的访问不连续的:可以通过一块大的连续的虚拟内存空间去访问物理内存中不连续的多个内存页中的数据。
- 使用大于实际物理内存的内存空间:程序可以通过虚拟内存地址来访问大于可用的物理内存的内存缓冲区。当物理内存不足时,内存管理器会将物理内存的内存页保存到磁盘中,程序的代码和数据的内存页会根据需要再物理内存和磁盘中进行交换。
- 进程间内存隔离:不同的程序进程使用虚拟内存进行隔离。
物理内存和磁盘中的内存页的交换策略
缺页时的内存置换算法
若地址映射过程中,发现物理内存中没有对应的内存页,就触发缺页中断,当发生缺页中断时,就需要将磁盘中的对应的内存页加载到内存中,如果此时内存中没有多余的内存页了,就需要按照一定的算法将现有的内存页保存到磁盘中,然后在加载需要的内存页。
置换算法有以下这些:
- 最佳置换算法:
- 先入先出置换算法:先使用的内存页就先被置换掉,简单的队列
- 最近未使用置换算法:每个使用的内存页都将记录一个T值,当需要置换时,计算T值和现在时间差,置换掉时间差最大的那个内存页
- 最少未使用置换算法:一个链表保存着最近使用的内存页,一个内存页使用了,就把这个内存页放到链首,需要置换的话就将链尾的内存页换掉,将新加载的内存页保存到链首。
问题
- 每一个进程都会分配一个内核空间和一个用户空间吗?
- 是的,每一个进程都会有对应的内核空间和用户空间。
- 那不同进程的内核空间是通用的吗?
- 在物理内存上,很多是通用的,如果需要内核缓冲区的话,就会在物理内存中分配实际需要的内存。
- 如何进行隔离的?哪来那么多的内存空间分配给那么多的进程使用?
- 通过虚拟内存技术进行隔离,虚拟内存可以将一部分的硬盘空间作为内存的临时存储不常用的内存页使用。