321_虚拟内存的基本概念
# 3.2_1_虚拟内存的基本概念
各位同学大家好,从这个小节开始,我们会开始学习虚拟内存相关的一系列知识点,这个小节我们会首先介绍虚拟内存的一些基本概念,在之前的小节中,我们知道操作系统对内存进行管理,需要实现对内存空间的分配与回收,对内存空间的扩充。 关于分配与回收这个问题,咱们之前介绍了一系列的传统的内存管理方案,包括基本分页、基本分段、基本段页式,还有什么固定分区、动态分区等等一系列的存储管理方式,在这些传统的存储管理方式的基础上,如果再加上覆盖技术或者交换技术的话,就可以使内存的利用率进一步的得到提升,能够从逻辑上扩充内存的容量。这个小节我们介绍的虚拟存储技术其实也是一种实现内存空间扩充的一种技术,它比交换技术和覆盖技术要更先进一些。
在这个小节中,我们会首先介绍传统的那些存储管理方式的特征,特别是缺点。那在人们发现了局部性原理之后,高速缓存技术又得到了进一步的发展,虚拟内存也是基于高速缓存技术的思想提出的一种内存管理方案。所以第二个部分我们会介绍局部性原理,还有高速缓存技术。那之后我们会介绍虚拟内存的定义和特征,最后我们还会简单的提一下虚拟内存技术应该怎么实现,我们会按照从上至下的顺序依次讲解。
# 传统的存储管理方式的特征、缺点
首先来看一下传统的存储管理方式的特征,特别是缺点。所谓的传统存储管理方式指的是咱们之前介绍的这一系列的,像基本分页、基本分段、基本段页式,还有什么固定分区、动态分区、单一连续分配这一系列的存储管理方案。
如果系统使用的是这些存储管理方案,那么很多暂时用不到的数据,其实也会长期的占用内存,导致内存的利用率不高。所以传统的这种存储管理方式有两个很明显的特征,
第一个叫做一次性,就是指作业必须一次性的全部装入内存之后才可以开始运行,由于这样的规定就导致了两个问题,当作业很大的时候,不能把全部的作业都装入内存,就导致大作业无法运行。就类似于咱们之前提到过的GTA那个游戏,本来需要60g的内存,如果说采用的是传统的这种存储管理方式的话,4GB的电脑是不可能运行60g大小的游戏的,所以这是它造成的第一个问题。作业大小超出内存的总容量的时候,这个作业肯定是无法运行的。
第二个问题,当大量的作业要求运行的时候,这些作业的大小总和可能已经超出了内存的总容量,这样的话内存就无法容纳所有的作业,但是所有的作业有要求,必须一次性全部装入内存才可以开始运行,因此其实内存当中是不可能支持这些所有的大量的作业都同时并发运行的,这样的话就导致了多道程序的并发度下降。所以这是传统存储管理方式的第二个特征,叫做驻留性:就是指一个作业,一旦放入内存之后,会一直驻留在内存当中,直到作业运行结束。
但实际上可能在一个时间段内,我们只需要访问一个作业当中的一小部分的数据,这个作业就可以正常开始运行了。比如说咱们在玩gta游戏的时候,如果说此时在游戏的a场景,那么b场景的资源就暂时不需要被加载到内存当中,我们只需要在内存当中放入a场景相关的资源,其实就可以保证这个游戏的正常运行了。但是如果说采用的是传统的这种存储管理方式的话,那么不管是a场景还是b场景的这些数据,都要求一直驻留在内存当中,无论此时是否需要这些数据,因此这样的话就导致了内存当中实际上是驻留了大量的暂时用不到的数据,从而导致了内存资源的浪费。
# 局部性原理
显然传统的存储管理方式其实存在很多缺点,这些缺点其实都可以用虚拟存储技术来解决。虚拟存储技术的提出其实是基于著名的局部性原理,局部性原理咱们在之前的课程当中也有简单的提到过,分为时间局部性和空间局部性
时间局部性指的是如果一个程序在执行的过程当中访问到了某一条指令或者某一个数据,那么此时访问到的这条指令或者数据在不久之后有可能会被再次访问到,因为程序当中存在着大量的循环,比如说在这个程序当中,由于存在这样一个循环,所以循环当中的这些代码指令有可能会很频繁的一次又一次的被访问,循环当中访问到的这些数据,比如说变量爱,也会被频繁的一次又一次的访问,所以这是时间局部性,
空间局部性指的是如果说此时访问了内存当中的某个存储单元的话,那么不久之后存储单元附近的那些存储单元有可能会被访问,导致空间局部性的原因是因为我们的程序当中很多数据其实是连续存放的,比如说数组a的这100个数组元素其实在内存当中是连续存放的,并且在程序当中访问数组a的时候,经常是需要连续的访问数组a当中的各个数组项的,而这些数组项在内存当中又是连续存放的,因此只要访问到了其中的某一个存储单元,那么就很有可能在不久之后访问与存储单元相邻的那些存储单元。
另一方面其实程序当中的这些指令在内存当中是连续的存放的,比如说循环当中的a[i] = i 这条代码对应的指令,还有i++这条代码对应的那一系列的指令,在内存当中都是连续存放的。由于我们的程序是顺序执行的,所以只要我们执行了第一条指令,那么就意味着与它相邻的存储单元当中存放的第二条指令,也很有可能在不久之后会被接着访问,所以这是造成空间局部性的一个原因。
这条代码对应的那一系列的指令,在内存当中都是连续存放的。由于我们的程序是顺序执行的,所以只要我们执行了第一条指令,那么就意味着与它相邻的存储单元当中存放的第二条指令,也很有可能在不久之后会被接着访问,所以这是造成空间局部性的一个原因。
我们应该怎么应用局部性原理?其实高速缓冲技术就是对局部性原理的一个很好的应用,高速缓冲技术的思想就是把近期会频繁访问到的那些数据放到更高速的存储器当中,暂时用不到的数据会放在更低速的存储器当中。
为什么要这么设计呢?这个地方就不得不提到计算机存储器的层次结构,外内存高速缓存寄存器,由下到上这些存储器,的呃速度越来越快,但是相应的制造这种更快的存储器所要花费的成本也会更高。因此在成本相同的情况下,速度越快的存储器容量会越小,像我们电脑当中的各种各样的软件程序,在未运行的时候都是放在容量很大的外存,也就是磁盘当中的,只有需要的时候才会把程序相关的数据调入更高速的内存当中。
由于内存的速度要比外存快很多,所以把这些程序的数据放到内存当中之后,可以更好的匹配高速的CPU处理这些数据的速度,暂时用不到的那些数据,我们放在外存中的话,也可以保证我们付出更少的成本就可以存放更多的东西。像之前咱们学过的快表机构,就是把近期会经常访问的快表项的副本放到更高速的联想寄存器当中,那由于局部性原理可知,现在访问过的这些页表像在不久之后也很有可能会频繁的被访问到,所以把这些很有可能会被频繁访问到的数据放到更高速的存储器当中,显然是可以提高我们系统效率的一种方案。快表机制就是一个局部性原理,还有高速缓冲技术的一个具体的应用。
其实高速缓冲技术的思想,咱们在平时生活当中也会使用到,比如说你买一个书架花了200块钱,书架上可以装很多的书,也就是说书架的容量大,成本低,但是你在书架上取书其实是不太方便的,因此我们又会买一个存书,取书速度更快更方便快捷的一个存储器,也就是书包,我们放到书包里的那些书,肯定是我们近期会频繁访问到的频繁使用到的一些书,所以采用这样的两极结构,也可以保证我们在存输取出很方便快捷的同时,也不用付出太多的成本代价。所以其实这个例子也是我们生活当中高速缓冲技术的一个应用。
# 虚拟内存的定义和特征
由于进程运行的过程中表现出了时间局部性,还有空间局部性,所以基于局部性原理,我们可以让程序在装入的时候,只是把程序当中很快就会使用到的部分,先放入到更高速的内存当中,然后暂时使用不到的部分暂时先留在外存,就可以开始让程序执行了。
如果程序执行的过程当中,想要访问的信息暂时还不在内存的时候,就需要由操作系统负责,把所需要的那些信息再从外存调到内存当中,然后再继续执行程序。
另外如果说内存的空间已经满了,内存空间不够的话,那么操作系统还需要负责把内存当中暂时用不到的那些信息数据换到外存当中。所以如果操作系统用这样的方式来管理内存的话,那么其实在用户看来,内存的容量是要比实际的内存容量大得多的,这就是虚拟内存技术,虚拟内存也是操作系统虚拟性的一个体现。
所谓的虚拟性指的是内存的实际物理容量其实是没有变的,只不过是通过操作系统的一系列的虚拟技术实现了从逻辑上扩充了内存的容量。
容易混淆的知识点:
这个地方需要强调一个虚拟内存相关的比较容易混淆的知识点,就是虚拟内存的最大容量和实际容量的确定。如果说题目中问的是虚拟内存的最大容量的话,那么最大容量是由计算机的地址结构,也就是CPU的选址范围来确定的。比如说如果一个计算机地址结构是32位按字节编制的话,那么在计算机当中虚拟内存的最大容量应该是二的32次方个字节,也就是4GB,这刚好是32位的CPU允许的一个选址范围。
但如果说题目中问的是虚拟内存的实际容量的话,实际容量是等于内存和外存的容量之和还有CPU的寻址范围,这两个数当中最小的。一个比如说在这个题当中内存大小是512M字节,然后外存是2GB,在这个系统当中虚拟内存的实际容量就应该是CPU的寻址范围4GB,还有内存与外存的容量之和之间的最小的一个因此在这个系统当中,虚拟内存的实际容量应该是2GB加512兆字节,这是在做题的时候有可能会遇到的一个点
在采用了虚拟内存技术之后,系统表现出了这样的几个主要特征,
- 第一个特征叫做多次性,就是指在作业运行的时候不需要一次性的全部装入内存,而是允许一个作业的数据被分为多次调入内存。
- 第二个特性叫兑换性,就是指在作业运行的时候,不需要一直让作业的所有数据都常驻内存,而是允许在作业运行的过程当中把作业的一些数据换入或者换出内存。多次性和兑换性刚好就对应了传统的内存管理方案当中的一次性和驻留性。
- 第三个的特性叫做虚拟性,就是指虽然说内存的实际物理容量没变,但是在用户看来从逻辑上是扩充了内存的容量的
可见在采用了虚拟内存技术之后,对内存的利用率还有系统的性能都是会有一定的提升的。
# 如何实现虚拟内存
那么怎么实现虚拟内存技术?首先我们需要明确的是,既然虚拟内存技术允许一个作业分为多次调入内存的话,那么如果说我们采用的是连续分配的方式,那么一个作业如果先调入了一部分,后一部分想要再调入的时候,还需要给作业分配与之前给它分配的内存空间,连续的一部分内存空间,也就是说采用连续分配的话,那么每一次给作业分配的内存空间都需要保证,都是连续的,所以这样实现起来其实很不方便。因此虚拟内存技术需要建立在离散分配的内存管理方式的基础之上
之前咱们学了几种传统的离散分配的存储管理,也就是基本分页,基本分段,还有基本段页式。在这些存储管理方式的基础之上,如果在应用虚拟内存技术的话,那么就形成了与它们相对应的请求分页请求分段,还有请求段页式存储管理
这种传统的存储管理方式,还有虚拟内存的存储管理方式,最主要的区别就在于,在虚拟内存技术当中,如果说在程序执行的时候,发现我们此时要访问的信息并没有在内存当中,那么操作系统需要负责把所需要的信息从外存调入内存,然后继续执行程序。
另外如果内存空间不够的话,操作系统还需要负责把内存当中暂时用不到的信息换出外存。
所以为了满足这两个全新的需求,操作系统需要在基本的这几种存储管理方式的基础上再增加两个主要的功能,第一个就是请求调页或者请求调段功能。
所谓请求调页就是指在请求分页存储管理当中,如果说我们所需要的页面暂时还不在内存当中,那么操作系统需要负责把这个页面从外存调入内存,并且完善一系列的处理。
第二个需要新增的主要功能是页面置换功能或者是段置换功能。当内存空间不够的时候,操作系统需要通过置换功能,把暂时用不到的分页或者暂时用不到的分段先换出外存当中。所以这就是实现虚拟内存技术的时候,我们需要最重点关注的两个功能。一个是请求调页功能,一个是页面置换功能。
当然这个地方的请求调页和页面置换对应的是请求分页存储管理方式,如果是请求分段存储管理方式的话,那么操作系统需要提供的就是请求调段,还有段置换的功能。
# 小结
那么小节当中我们介绍了虚拟内存管理的一系列基本概念,传统的存储管理方式存在着一次性、还有驻留性这样两个比较明显的特征,这两个特征也导致了传统管理方式存在了一系列的缺点。
不过基于局部性原理提出的虚拟内存技术,其实可以解决传统存储管理方式当中的这些缺点的,局部性原理分为时间局部性还有空间局部性,这两个知识点大家需要理解,在选择题当中还是很有可能进行考察的。
基于局部性原理,人们提出了各种各样的高速缓存技术,他们的核心思想就是需要把频繁使用的数据放到更高速的存储器上,但是暂时用不到的或者使用频率低的可以放在更低速的那些存储器上。虚拟内存技术其实也是局部性原理,还有高速缓存技术的一个进一步的应用和拓展。
那在采用了虚拟内存技术之后,系统体现出了多次性、对换性,还有虚拟性这些全新的特征,
多次性和对换性,与传统存储管理方式当中的一次性还有驻留性,刚好是一一对应的,大家需要对比着来理解和记忆。
最后我们探讨了怎么实现虚拟内存技术,我们重点需要关注的是请求调页功能,还有页面置换功能,不过这些功能我们会在之后的小节当中进行更详细的学习。
虚拟内存的实现主要分为请求分页、请求分段,还有请求段页式存储管理这样三种方式,之后我们会重点介绍请求分页存储管理方式。