虚拟内存是操作系统里面的概念,我们都知道计算机总体上由硬件和软件两部分组成:
硬件包括:cpu处理器,内存条,磁盘IO设备
软件包括:操作系统,运行在操作系统之上的各种程序
一个简单计算机系统的组成图示如下:
而虚拟内存归属于操作系统,是操作系统里面非常重要的一个概念,操作系统的主要作用有两个:
(1)对下保护硬件设备,避免受到运行在上面的应用程序误用
(2)对上则通过操作系统这个中介程序屏蔽了底层的操作的复杂性,提供了统一和简单的访问接口
我们看下操作系统的抽象分层,如下图所示:
从上图我们能够看到,操作系统的抽象分层:
(1)文件作为所有的I/O设备的抽象
(2) 虚拟内存作为I/O设备+主内存的抽象
(3)进程作为cpu处理器+主内存+I/O的抽象
从上面的包含关系里可以看到,进程是基本的抽象体,任何程序本身都是一个进程,进程抽象了硬件底层的所有设备,包含cpu,内存和I/O设备。
而虚拟内存则由主内存+I/O设备组成,或者简单点说,虚拟内存包内存和磁盘。
虚拟内存是一种存储模式,通过这种模式能让我们有种感觉,即:我们的内存本身能够处理远比内存大的多的数据或者文件。
虚拟内存能够处理比本身更大的数据的原理其实非常简单,你可以简单理解为按需加载,在操作系统里面这种方式有个专有的称呼:Demand Paging,这是虚拟内存管理的一种最常见的策略。
能这么做的原因是存储在磁盘上的文件,在底层都会按照固定大小的page进行划分,我们在使用cpu处理磁盘上的文件的时候,并不是一下会把整个文件都载入内存,而是当用到这部分数据的时候才会去加载,也就是说一个page被拷贝进主内存的触发机制是:
(1)这块数据需要被加载
(2)当发生操作系统发起缺页信号时
也就是说在虚拟内存里面,我们可以开辟一个固定大小的区域用来处理相关的数据,在加载数据时,如果这个区域没有满,就直接读满,如果满了之后,系统要读取新的page时,会发现这个page不在虚拟内存里面,就会发起一个缺页信号,为了读取新的数据进入内存,我们可以释放掉前面已经处理过的数据,然后加载新的page替代被淘汰数据的page占的位置,被淘汰page的处理,我们可以直接丢弃,也可以将其再次保存在磁盘上存储,防止将来还需要读取。
通过这样的方式,我们可以使用一块特定的大小的区域,用来源源不断的处理一份比这个空间大数10倍或者100倍的体积。通过充分利用磁盘来和内存交换存储空间,来使得我们的有限的内存资源看起来能够处理不限大小的数据或者文件。
前面提到,如果在内存里面申请的固定空间满了,会淘汰一部分page然后替换为新的page,这里面的这个算法非常关键,算法的好坏决定了内存要和磁盘发生swap的次数,这个次数直接直接影响了程序的性能。
缓存驱逐(过期)算法常用的策略有三种,分别是:
(1) FIFO:First In First Out,先进先出策略
(2) LFU:Least Frequently Used,最不经常使用策略
(3) LRU:Least Recently Used,最近最少使用策略
这个后面会具体介绍,这里不再展开。
优点:
(1)可以使用有限的内存资源,处理比实际内存更大的文件或者数据
(2)更加高效的内存利用
(3)在有限的内存资源内,让系统运行更多的程序实例,因为每个程序都是按需取。
缺点:
(1)如果内存严重不足,而处理超级大的文件时,会频繁引起内存和磁盘进行swap,从而降低系统性能。
(2)在多个应用程序之间切换会花费更多的时间
(3)虚拟内存本质上是充分了磁盘空间,但同时变相的提供用户使用的实际磁盘空间也会变小。
本文主要介绍了操作系统和虚拟内存的关系,以及虚拟的内存概念,工作原理,page替换策略,优缺点等内容,虚拟内存是一个非常有用的抽象概念,通过巧妙的设计主存和磁盘的交互,来大大提高了内存的使用率,但凡事都有利弊,针对虚拟内存的不足之处,我们也应该有一个清晰的认识,从而取长补短,设计出更加健壮的程序。
参考链接:
https://www.javatpoint.com/os-virtual-memory
https://www.tutorialspoint.com/operatingsystem/osvirtual_memory
《深入理解计算机系统》