虚拟内存

使系统拥有一个连续完整的地址空间的内存管理技术

虚拟内存

虚拟内存(Virtual Memory),[0]是计算机系统内存管理的一种技术,它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,当计算机缺少运行某些程序所需的物理内存时,操作系统会使用硬盘上的虚拟内存进行替代。[5]在虚拟内存概念提出前,计算机内存管理依靠随机存取存储器(RAM)和辅助存储,面临程序规模增长与内存成本高昂的挑战。[6]虽然关于虚拟内存概念的首次提出存在一些争议,但普遍认为是由德国物理学家弗里茨·鲁道夫·冈施(Fritz-Rudolf Güntsch)于1956年率先提出,[7]英国曼彻斯特大学于1959年开发的Atlas计算机实现了分页技术,成为早期采用虚拟内存技术的系统之一,[8][6]而伯勒公司(Burroughs Corp.)随后于1961年推出了首款商用的虚拟内存计算机系统。[7]1982年,英特尔在80286处理器中引入虚拟内存技术,并在1985年的80386处理器中提供分页支持,推动了个人电脑技术的快速发展[7][6]。

虚拟内存(Virtual Memory),[1]计算机系统内存管理的一种技术,它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,当计算机缺少运行某些程序所需的物理内存时,操作系统会使用硬盘上的虚拟内存进行替代。[6]

在虚拟内存概念提出前,计算机内存管理依靠随机存取存储器(RAM)和辅助存储,面临程序规模增长与内存成本高昂的挑战。[7]虽然关于虚拟内存概念的首次提出存在一些争议,但普遍认为是由德国物理学家弗里茨·鲁道夫·冈施(Fritz-Rudolf Güntsch)于1956年率先提出,[8]英国曼彻斯特大学于1959年开发的Atlas计算机实现了分页技术,成为早期采用虚拟内存技术的系统之一,[9][7]而伯勒公司(Burroughs Corp.)随后于1961年推出了首款商用的虚拟内存计算机系统。[8]1982年,英特尔在80286处理器中引入虚拟内存技术,并在1985年的80386处理器中提供分页支持,推动了个人电脑技术的快速发展[8][7]

虚拟内存器的调度方式包括分页式、段式和段页式。[10]影响虚拟内存的因素包括设置虚拟内存的大小、存储位置、内存管理单元等,[11][12]涉及到地址变换、替换算法等重要技术,[4][5]其具有扩大地址空间、对特定的内存地址提供写保护和公平分配内存等优点,[13]但同时也存在浪费内存、增加指令的执行时间等局限性。[13]此外,虚拟内存广泛应用在多任务操作系统、大型应用程序等场景中。[2][3]

背景

在虚拟内存的概念被提出之前,计算机的内存管理主要依赖于随机存取存储器(RAM)和辅助存储器。在早期的计算机系统中,磁芯存储器被用作主存储器,而磁鼓则作为辅助存储器使用。然而,在20世纪40年代和50年代,由于存储器的价格昂贵且供应不足,程序的大小和复杂性不断增加使得内存管理成为了一个迫切需要解决的问题。[8][7]

为了解决这个问题,早期程序员通过覆盖的过程来运行大于可用内存的程序,这种技术将程序中不常使用的部分设置为可覆盖状态,当需要运用内存时,这些部分可以覆盖内存中已有的内容。实施覆盖需要精细的编程工作,为了提升效率和简化操作,开发自动化虚拟内存技术已成为当时主要的内存发展方向。[8]

早期

虽然关于虚拟内存概念的首次提出存在一些争议,但普遍认为是由德国物理学家弗里茨·鲁道夫·冈施(Fritz-Rudolf Güntsch)于1956年率先提出,尽管他描述的只是一种高速缓存存储器的形式,但他的研究为虚拟内存的发展奠定了基础。[8]

英国曼彻斯特大学的Atlas计算机是早期实现虚拟内存的系统之一,[9]于1959年开发,并于1962年开始使用,其采用了分页技术,将虚拟地址映射到物理内存。[8][7]

1961年,伯勒公司(Burroughs Corp.)推出了首款商用的虚拟内存计算机系统,这款计算机采用了分段的方式来管理虚拟内存,而非传统的分页管理。[8]

1960年代中期,IBM在托马斯·J·沃森研究中心(Thomas J. Watson Research Center)进行M44/44X计算机研究项目。[注1]M44/44X项目基于IBM 7044(M44)[注2]实现了多个具有突破性的虚拟化概念,包括部分硬件共享(partial hardware sharing)、[注3]时间共享(time sharing)、[注4]内存分页(memory paging)[注5]等,并实现了虚拟内存管理的虚拟机监视器。[注6]通过这些虚拟化技术,应用程序可以运行在这些虚拟的内存之中,实现了在同一台主机上模拟出多个7044系统(44X)。M44/44X项目首次使用了虚拟机(Virtual Machine,VM)[注7]和虚拟机监视器(Virtual Machine Monitor,VMM)[注8]一词,被认为是世界上第一个支持虚拟机的系统。[21]

1969年,随着IBM相关人员的研究,证明了虚拟内存覆盖系统相较于早期手动系统具有更高的效率,虚拟内存技术开始逐渐得到广泛的认可和应用。随着时间的推移,虚拟内存技术逐渐成为了大型计算机和小型计算机的标配。[8]

发展

1982年,英特尔在80286处理器[注9]保护模式[注10]下引入了虚拟内存技术,并在1985年为80386[注11]的推出提供了分页支持,带动了个人电脑技术的快速发展。[8][7]

2000年,作为真正意义上的第一个功能完整的操作系统虚拟化技术,FreeBSD jail[注12]得到迅速发展。利用这个技术,FreeBSD[注13]的系统管理者可以创造出几个小型的软件系统,这些软件系统被称为监狱(jails)。[21]

2004年,微软发布Virtual Server 2005计划,象征着虚拟化技术正式进入主流市场。[21]

2010年10月21日,NASA发布了云操作系统OpenStack[注14],推动了云计算在中国的全面爆发。2011年5月,IBM和红帽,联合惠普英特尔一起,成立了开放虚拟化联盟(Open Virtualization Alliance)。[21]

工作原理

在启用虚拟内存时,每个程序都有不同的虚拟内存空间,可以自由访问预先定好的内存地址,而实际保存在物理内存的地址则交给内存管理单元管理。虚拟内存中的内容不仅可以保存在物理内存中,而且可以保存在硬盘中,也就是所谓的分页文件(Swap)。当物理内存不足时,操作系统可以把一部分内容转移到硬盘上的虚拟内存文件,下次使用到该部分内容时再从虚拟内存文件转移回物理内存。[1]

程序A发出了“写入4字节到内存地址0x1020”的指令,CPU实际上可能在物理内存地址0x2020处进行写入操作;而当程序B执行相同的“写入4字节到内存地址0x1020”的指令时,CPU可能选择在物理内存地址0x4020处进行写入。这样,虽然程序A和程序B使用的是相同的虚拟内存地址,但实际的物理内存地址不同,因此它们的操作不会互相影响。[1]

程序A与程序B的虚拟内存范围对应的物理内存范围
程序A与程序B的虚拟内存范围对应的物理内存范围

地址变换

地址变换是逻辑地址到物理地址的变换。一般情况下,一个作业在装入内存时分配到的存储空间[注15]和它的地址空间[注16]是不一致的。因此,作业在CPU上运行时,其所要访问的指令和数据的物理地址与地址空间中的逻辑地址是不同的。如果在作业装入内存或者在它运行时不对相关地址加以修改就会导致错误的结果。这种由于一个作业装入与其地址空间不一致的存储空间所引起的对有关地址部分的调整,就是地址变换,又称为地址重定位。这种地址变换的过程也称为地址映射[4]地址变换的目的,是消除在高级寻址方式中程序地址与物理地址的语义差距,使程序能够在任意位置的物理内存中运行,而不必关心其物理位置。[25]

进程地址空间和存储空间变换
进程地址空间和存储空间变换
形式概述
全联想变换任何逻辑空间页面能够变换到物理空间任何页面位置的方式
直接变换每个逻辑空间页面只能变换到物理空间的一个特定页面的方式
组联想变换各组之间的变换是直接变换,而组内各页面的变换则是全联想变换
[5]

替换算法

替换策略在任何一个调页系统中都很重要。在为调页系统设计替换策略时,可以选择很多种算法。页面替换算法通常从实际程序执行过程中收集引用串,评估算法对引用串产生的效果来衡量,同时也可以对算法采用形式化分析,但是除非对执行环境增加很多限制条件,否则这种分析很困难。衡量页面替换算法效率最常用的指标是缺页率。[26]常用的替换算法包括以下四种:[5]

随机算法

随机(Random)算法是指通过算法从服务器列表中随机选取一台服务器进行访问。结合概率论的相关知识可知随着客户端调用服务器端的次数增多,其实际效果趋近于平均分配请求到服务器端的每一台服务器,即达到轮询的效果。算法描述如下:[27]

假设有N台服务器S=|S0,S1,S2.…,Sn|,算法可以描述为通过随机函数生成0~N之间的任意整数,将该数字作为索引,从S中获取对应的服务器。假定现在有4台服务器初始化服务列表后,每台服务器对应一个地址,地址分别有相应的权重,见下表。[27]

服务器地址权重
10.0.0.11
10.0.0.32
10.0.0.33
10.0.0.44
参考文献[27]

随机算法与服务器权重没有关系,每个服务器会被随机地访问到。由概率论可以得知,当样本量足够大时,每台服务器被访问到的概率近似相等,随机算法的效果就越趋近于轮询调度算法,将请求随机分配到各节点。随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配,也就是轮询的结果。[27]

随机算法简单示例
随机算法简单示例

先进先出算法

先进先出(FIFO)算法根据块在内存Cache)中的时间长短作为替换依据。FIFO算法认为是最早调入Cache中的块,其以后不再被使用的可能性比刚调入的可能性大,故总是选择在Cache中停留时间最长的块替换。在算法实现上,将进入Cache的块按照时间先后顺序排队,队首是最早进入Cache的块,队尾是最晚进入Cache的块,需要替换时,队首的块首先被替换掉。[28]

先进先出分页替换法
先进先出分页替换法

近期最少使用算法

近期最少使用算法(LRU)的基本思想是挑选近期最久没有使用过的块作为被替换块,这种算法能较好地反映程序的局部性特点。LRU算法可用堆栈来实现,所以又称为堆栈型算法。当所设堆栈已满,又有一块要求调入cache时,首先检查堆栈中是否已经有这一块。如果有,则将这一块从堆栈中取出压入堆栈的栈顶;如果没有,则将该块直接压入栈顶,于是在原栈底上的块被压出了堆栈,保证任何时候栈顶上的块总是刚被访问过的块,而栈底上的块总是最久没有被访问过的块。[29]

使用一个链表保存缓存数据
使用一个链表保存缓存数据

最佳置换算法

OPT置换算法是由贝莱迪(Belady)于1966年提出的一种理论上的算法。其所选择的被淘汰页面,将是以后永不使用的,或者是在未来的最长时间内不再被访问的页面。采用最佳置换算法,通常可保证获得最低的缺页率。但由于人们还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,但可以利用该算法去评价其他算法。[4]

最佳置换算法
最佳置换算法

工作过程

虚拟存储器是由硬件和操作系统自动实现存储信息调度和管理的。它的工作过程包括6个步骤:[10]

中央处理器访问主存的逻辑地址,将其分解成组号a和组内地址b,并对组号a进行地址变换,即将逻辑组号a作为索引,查地址变换表,以确定该组信息是否存放在主存内。[10]如该组号已在主存内,则转而执行4,如果该组号不在主存内,则检查主存中是否有空闲区,如果没有,便将某个暂时不用的组调出送往辅存,以便将这组信息调入主存。[10]从辅存读出所要的组,并送到主存空闲区,然后将那个空闲的物理组号a和逻辑组号a登录在地址变换表中。[10]从地址变换表读出与逻辑组号a对应的物理组号a。[10]从物理组号a和组内字节地址b得到物理地址。[10]根据物理地址从主存中存取必要的信息。[10]

调度方式

调度方式有段式、分页式、段页式3种。[10]

段式

程序通常具有模块性,一个复杂的大程序总可以分解成多个在逻辑上相对独立的模块,这些模块可以是主程序、子程序或过程,也可以是数据块。模块的大小各不相同,有的甚至事先无法确定,每个模块都是一个单独的段,都以该段的起点为0相对编址。当某个段由辅存调入主存时,只要赋予该段一个基地址(即该段存放在主存中的起始地址),就可以由此基地址和单元在段内的相对位移形成单元在主存中的实际地址。将主存按段分配的存储管理方式称为段式管理。[30][31]

假设系统在主存中最多可同时有N道程序,可设N个段表基址寄存器[注17],对应于每道程序,由基号(程序号)指明使用哪个段表基址寄存器,段表基址寄存器中的段表基地址字段指向该道程序的段表在主存中的起始地址,段表长度字段指明该道程序所用段表的行数即程序的段数。由系统赋予某道程序(用户、进程)一个基号,并在调入/调出过程中对有关段表基址寄存器和段表的内容进行记录和修改。[30][31]

段式管理的定位映像机构及地址的变换过程
段式管理的定位映像机构及地址的变换过程

分页式

段式存储中各段装入主存的起点和各段长度是随意的,段表中的地址字段和段长字段很长,增加了辅助硬件开销,降低了查表速度,导致主存管理繁琐。例如,主存中已有A、B、C三个程序,其大小和位置如图所示,现有一长度为12KB的D道程序想要调入。段式管理时尽管D道程序长度小于主存所有可用区零头总和16KB,但是没有零头能装得下,所以无法装入,页式存储由此开始发展。[30][31]

页式存储是把主存空间和程序空间都机械等分成固定大小的页(页面大小随机器而异,一般在512B到几KB之间),按页顺序编号,任一主存单元的地址np就由实页号nv和页内位移nt两个字段组成。每个独立的程序也有自己的虚页号顺序,如此例中,若页面大小取4KB,则独立编址的D程序就有3页长,页号为0-2。如果虚拟内存中的每一页均可装入主存中任意的实页位置,如下图所示,D程序中各页就可分别装入主存的第2、6、7三个实页位置,只要系统设置相应的页(映像)表,保存好虚页装入实页时的页面对应关系,就可由给定的程序(虚)地址查页表,变换成相应的实(主)存地址访存。[30][31]

采用页式存储后D道程序仍可装入
采用页式存储后D道程序仍可装入

页面调度策略

虚拟内存系统定义了三种分页调度策略:取页策略、置页策略和替换策略。[32]

取页策略:决定什么时候页面调度程序把一个页从磁盘调入内存中,取页策略有两种做法,一种是尽量把一个进程需要的页面在使用之前就装入内存,另一种是按需页面调度策略,即仅当发生页面错时才将所需页装入。[32]

置页策略:是指当一线程收到一个页面错时,内存管理系统必须确定把页面放入物理内存中什么地方。在段式内存体系结构中,置页策略较复杂,但在线性结构中较简单,它只要求找到一个未分配的页帧。[32]

替换策略:是指当产生页面错误且物理内存已满时,使用什么算法来确定哪一个虚拟页要从内存中移去,以便为新的页留出空间,常用的替换算法有近期最少使用算法和先进先出算法。[32]

段页式

段页式存储是把实(主)存机械等分成固定大小的页,程序按模块分段,每个段又分成与实(主)存页面大小相同的页。每道程序通过一个段表和相应的一组页表进行定位。段表中的每一行对应一个段,其中“装入位”表示该段是否已装入主存,若未装入主存,则访问该段时将引起段失效故障,请求从辅存中调入页表;若已装入主存,则地址字段指出该段的页表在主存中的起始地址。[31]

对于多道程序而言,每道程序(用户或进程)都需要有一个用户标志号u(转换成基号b)以指明该道程序的段表起点存放在哪个基址寄存器中,从而使多用户虚地址就由用户标志u、段号s、页号p、页内位移d四个字段组成。设系统中主存最多可容纳N道程序,下图表示采用段页式管理的定位映像机构及由多用户虚地址变换成主存实地址的过程。[31]

段页式管理的定位映像机构及其地址的变换过程
段页式管理的定位映像机构及其地址的变换过程

在虚拟存储器中每访问一次主存都要进行一次程序地址向实(主)存地址的转换。段页式的主要问题是地址变换过程至少需要查表两次,即查段表和页表。因此,要想使虚拟存储器的速度接近于主存,必须在结构上采取措施加快地址转换中查表的速度。[31]

调度方式优点缺点
段式消除了内存零头,易于实现存储保护,便于程序动态装配调入操作复杂
分页式页内零头小,页表对程序员来说是透明的,地址变换快,调入操作简单各页不是程序的独立模块,不便于实现程序和数据的保护
段页式综合了段式和页式的优点增加了硬件成本,软件也较复杂
参考文献[10]

内存大小

为虚拟内存分配合适的硬盘空间的大小非常重要,如果虚拟内存设置不当,就可能导致出现内存不足问题,如果分配太小,会出现“存储器用完”错误。因此可以把虚拟内存文件的最小值和最大值设为相同值,就会迫使操作系统在开机时就分配整个页文件,防止程序在运行过程中增大页文件,从而改进性能。许多图像应用程序可因此避免在硬盘和磁带之间读写图像信息时停顿,通过减少操作系统调整页文件大小的需要,从而减少了对磁盘的写操作。[11][33]

存储位置

影响虚拟内存性能的另一个因素是页文件在磁盘上的存储位置。系统盘空余的容量并不小,但因为经常安装、下载软件,并反复删除造成文件碎片太多,也会造成虚拟内存不足。虚拟内存需要一片连续的空间,尽管磁盘空余容量大,但没有连续的空间,也无法建立虚拟内存区。[33]如果系统有多个物理硬盘,可以把每个驱动器上的页文件减小,而把工作分配到各个驱动器,从而使频繁使用虚拟内存的系统大大加速。[11]

文件碎块

磁道和扇区上产生大量属于同一个程序但又非连续存放的数据簇,即所谓的文件碎块。当这些碎块积累到一定程度,有可能导致文件丢失数据,更重要的是导致硬盘读写数据的速度严重下降,并且会使得系统的高速缓存程序如SmartDrive的性能也大打折扣,影响到虚拟内存的工作效率。[34]

内存管理单元

内存管理单元中,处理器的虚拟地址空间被划分为页面大小的分配单元。内存管理单元能够将虚拟内存分为内核空间和用户空间,内核空间保留给操作系统和相关组件(如设备驱动程序)使用;用户空间可供应用程序使用,也可以用于用户启动的其他操作,例如处理输入到命令提示符窗口中的命令。用户级代码无法直接访问系统内存,必须调用系统函数来请求内存分配等服务。[12]

系统负载

处理器的速度影响各个任务的执行速度,同时它能够将硬盘空间用作虚拟内存,当系统的全部RAM都被用完时,就可以通过将内存块换进或换出硬盘而继续执行其他的运算。但一旦系统负载过大而需要使用虚拟内存时,会因为硬盘驱动器的速度比RAM芯片慢而使系统的性能明显下降。[35]

优点

允许程序分段加载到内存:虚拟内存可以使得大程序在主存配置比程序本身还小的机器上运行。对于内存大小中等的机器,由于程序运行时不必全部驻留内存,虚拟内存允许更多的程序驻留在主存中竞争CPU时间,当程序一段时间内只使用部分代码段或数据段,而不用其他部分的时候,那些没有用到的部分就不用放在内存中。另外,使用虚拟内存可以加速程序启动,通常程序在处理命令行参数和决定采取何种操作之前,只需要把一小段代码载入内存,在程序的一次执行过程中,可能不需要程序的其他部分。随着程序不断运行,其代码段和数据段的其余部分在需要时才被调入内存(请求调页机制)。[36]

为算法技术提供支持:相比仔细地将数据结构放到较小的内存区域,有许多算法更容易通过稀疏使用大地址空间进行编程实现。如果不用虚拟内存,这些技术实现起来代价太大。但是一旦有了虚拟内存,在没有太多物理内存的情况下,它们依然会运行得更快。[36]

扩大了地址空间:无论段式虚拟内存,还是页式虚拟内存,或是段页式虚拟内存,寻址空间都比实存大。[13]

公平分配内存:采用了虚拟内存之后,每个进程都相当于有同样大小的虚拟内存空间。[13]

实现进程间通信:当进程需要通信时,可采用虚拟内存共享的方式实现。内存页可以标记为可在应用程序间共享,这意味着一个页面被明确授权为可以从多个进程进行访问。这实现了有效的进程间通信。[13][37]

确保操作系统正常运行:由于每个内存页都有一组属性,这些属性限制了该页面所支持的操作类型,通过合理设置这些属性,可以提高操作系统稳定性。虚拟内存管理硬件负责确保每个应用程序只能访问分配给它的内存页。试图访问另一个进程的内存或其分配的内存空间之外的任何其他地址,都会导致访问冲突异常。[37]此外,虚拟内存能够特定的内存地址提供写保护,以防止代码或数据被恶意篡改。[13]虚拟内存还可以将内存页标记为所需的最低权限级别,从而仅允许内核级代码访问该内存页,此限制可确保即使在应用程序运行异常的情况下,操作系统也可以正常运行。[37]

局限性

降低性能:使用虚拟内存会降低性能。把程序一次性载入内存,要比根据需要一块块地将整个程序载入内存的效率高得多。因为每次操作都需要一定的开销:保存和恢复状态决定必须载入哪个页面。所以,有些系统只对大小超过某一最小值的程序才使用请求调页机制。[36]

地址映射问题:在访问主存时把虚地址变为主存物理地址(这一过程称为内地址变换):在访问辅存时把虚地址变成辅存的物理地址(这一过程称为外地址变换),以便换页。此外还要解决主存分配、存储保护与程序再定位等问题。[30]

占用内存虚拟内存的管理需要建立很多数据结构,这些数据结构要占用额外的内存。此外,如果一页中只有一部分数据,会浪费内存。[13]

耗费时间:虚拟地址到物理地址的转换,增加了指令的执行时间。此外,页面的换入换出需要磁盘I/O,也需要耗费时间。[13]

安全与隔离

随着虚拟化技术的发展,越来越多的单位将业务应用迁移至虚拟计算平台,相应地,针对虚拟计算环境的恶意代码也日益猖jué。2016年发布的《2015年中国互联网服务器安全报告》显示,虚拟服务器及云平台已成为黑客攻击的主要目标之一。虚拟环境恶意行为的一个最大特点是内存化、隐蔽化以及多态,使得部分关键数字证据只存于易失性内存中或暂存于页面交换文件中。虚拟环境恶意行为分析技术主要分为虚拟隔离环境分析、虚拟机监控器外部分析以及虚拟机内部分析等。[38]

虚拟隔离环境分析

虚拟隔离环境分析技术利用虚拟机隔离恶意软件运行环境,在虚拟机内部安装分析软件或使用APIHOOK等方式捕获恶意软件行为,可通过驱动方式加载内部分析系统,利用APIHOOK技术分析恶意软件行为。[38]

虚拟机监控器外部分析

虚拟机监控器外部分析技术利用虚拟机监控器(virtual machine monitor,VMM)实现虚拟机代理或自省,捕获虚拟机内部恶意软件的运行行为并加以分析。可利用虚拟机自省技术实现虚拟机内部运行状态的监控与行为重构。[38]

虚拟机内部分析

虚拟机内部分析技术可利用虚拟机自身的某种功能特性实现恶意行为的分析,可通过虚拟机的软件模拟特性完成了恶意软件动态行为检测并通过增量获取内存数据,实现恶意行为的连续分析。[38]

序列化重构

为动态刻画虚拟计算环境中的进程行为,须将虚拟内存中获取到的多个单一行为以证据链的方式进行序列化重构。如图所示,针对主流的虚拟计算环境(如VMware),通过VMware虚拟机安装目录下扩展名为.wmem的文件获取内存镜像,通过对该文件的逆向分析破解其数据结构,遍历搜索内核对象,从而准确定位并提取相应的原始内存证据信息。[38]

基于虚拟环境内存的恶意行为提取模型
基于虚拟环境内存的恶意行为提取模型

权限控制和内存资源隔离

从密码软件实现所需的运行环境来看,计算机通过软硬件配合实现了权限控制和内存资源隔离,具体包括:虚拟内存管理是操作系统基于软硬件机制实现的内存管理功能,通过将用户态进程使用的虚拟地址映射内存的物理地址,使得用户态进程拥有连续的虚拟地址空间,同时也便于操作系统内核更好地控制程序对资源的申请和使用,控制进程可访问资源的范围并且限定进程异常后影响的范围,防止其他进程非法读取和写入进程资源保证用户态进程访问资源互不影响。[39]

权限控制和进程隔离是主流密码软件实现所依赖的重要基础,密码软件实现所在进程中的密钥等敏感信息被安全地逻辑隔离,使得其他恶意进程无法随意访问。内核态和用户态的隔离是最基本的基于硬件特权机制的内存地址空间隔离,而且随着技术的发展,出现了利用CPU硬件的虚拟机监控器的内存地址空间隔离、利用CPU硬件机制的可信执行环境等新型隔离机制。[39]

多任务操作系统

在支持多任务的操作系统中,如果所有任务的内存需求加起来的总量超过了当前系统的物理内存总量,那系统要么停掉一些任务,要么把一些任务转移到外存(如磁盘)中,以后当内存空闲时再把这些任务转换回来;或者系统有选择地把部分不常用的内存转换到外存,并且根据适当的规则将来再慢慢地转换回来。[40]

Windows多任务操作系统

Windows多任务操作系统采用虚拟内存的管理方式,对虚拟内存的管理完全靠操作系统控制,它让每个在系统中运行的作业都认为自己有足够的内存空间,而事实上虚拟内存的空间是由内存和外存共同构成的,这种足够的内存空间的感觉是由程序页面在内存与外存之间交换实现的。程序运行初始,通常只装入必要的页面在内存,其余的都放在辅存中,在需要的时候,将外存的相应页面交换到内存中,保证程序的正常运行。[2]

Linux多任务操作系统

Linux多任务操作系统采用的是请求页式虚拟内存管理技术,它为应用程序提供比实际内存大得多的虚拟内存。当一个程序执行时,Linux只为它分配虚拟空间,只有发生缺页中断时,才为它分配物理空间,将虚页装入内存,即只将当前运行最需要的代码和数据装入内存。这样,当该程序运行结束时,会有一些页面从未装入内存(比如错误处理代码,帮助代码),最大限度地利用了主存空间,因而可使更多的程序同时运行。[2]

大型应用程序

20世纪70年代,由于当时的存储容量,特别是内存容量成本非常高,容量也很小,对于大型应用程序或多程序的应用就受到了很大的限制。为了克服这样的限制,人们就采用了虚拟存储的技术,最典型的应用就是虚拟内存技术。[41]Windows为例,Windows采用“请页式”虚拟内存管理技术,运行于386以上的机器上,提供32位虚地址,每个进程都有多达4GB(232B)的虚地址空间。进程4GB的地址空间被分成两部分:高地址的2GB保留给操作系统使用,低地址的2GB是用户存储区,可被用户态和核心态线程访问,Windows提供一个引导选项,允许用户拥有3GB地址空间,留给系统1GB以改善大型应用程序运行的性能。[3]

物理内存

物理内存也称为实际内存,是指有硬件存储介质的内存。在实际内存管理中,必须为作业分配足够的存储空间,以装入有关作业的全部信息,作业的大小不能超出主存的可用空间,否则,这个作业无法运行。事实上,当把有关作业的全部信息都装入主存储器后,作业执行时不是同时使用全部信息的,有些部分只运行一遍,有些部分在作业执行的整个过程中甚至都不会被使用(如错误处理部分)。[42]

比较量虚拟内存物理内存速度较慢较快金额较便宜较贵技术分页技术交换技术内存受限内存芯片硬盘CPU访问直接访问——参考文献[8]

参考资料 42

  1. 参考 1
  2. 参考 2
  3. 参考 3
  4. 参考 4
  5. 参考 5
  6. 参考 6
  7. Virtual Memory — denninginstitute
  8. What is virtual memory? — techtarget
  9. Timeline of Computer History — computerhistory
  10. 参考 10
  11. 参考 11
  12. 参考 12
  13. 参考 13
  14. 参考 14
  15. 参考 15
  16. 参考 16
  17. 参考 17
  18. 参考 18
  19. 参考 19
  20. 参考 20
  21. 虚拟化技术发展史 — 江西工程学院智慧产业学院
  22. 参考 22
  23. 参考 23
  24. 参考 24
  25. 参考 25
  26. 参考 26
  27. 参考 27
  28. 参考 28
  29. 参考 29
  30. 参考 30
  31. 参考 31
  32. 参考 32
  33. 参考 33
  34. 参考 34
  35. 参考 35
  36. 参考 36
  37. 参考 37
  38. 参考 38
  39. 参考 39
  40. 参考 40
  41. 参考 41
  42. 参考 42

注释

  1. “M44/44X”计算机项目定义了虚拟内存管理机制,对于用户来说,这些虚拟内存就好像一个个“虚拟机”,为多个用户的程序提供了独立的计算环境。[14]
  2. 1965年,IBM公司发布的IBM7044计算机最早在商业系统上实现虚拟化。IBM7044为主机创建多个虚拟镜像,为多个用户的程序提供了独立的计算环境,允许在一台主机上运行多个操作系统。每个镜像叫作7044/44X,多个用户能够通过虚拟镜像访问主机的内存和资源。从本质上来说,IBM7044定义了虚拟内存管理机制,应用程序可以运行在虚拟内存中。从用户的角度来看,这些虚拟内存就好像是一个个独立运行的虚拟机,分别供不同用户的程序来运行计算。[15]
  3. 硬件共享是网络用户对网络系统中的各种硬件资源的共享,如主计算机、网络打印机、磁盘阵列、扫描仪、绘图仪、通信线路和设备等。[16]
  4. 1960年美国国防部高级研究规划署技术处理处第一任处长立克里德(U.C.R.Licklider)在其发表的《人-计算机共生关系》一文中,首次提出“时间共享”的概念。其意是指不需要中间操作人员实现人与计算机的直接对话。[17]
  5. 内存分页是以页为单位给运行程序分配内存单元。当内存空间不够时,页面可转入磁盘上,分页主要用于虚拟存储多任务操作系统中,与分段不同,分段是将程序、数据块分成一些可变长度的段,而分页则是将程序分成多个同样大小的页面,每段一页或多页。[18]
  6. M44/44X项目中的虚拟机是通过一种名为虚拟机监视器的虚拟化软件实现的,VMM可通过在硬件层上建立一个虚拟层,将计算机硬件分割成多个虚拟机,并提供多用户对大型计算机的同时交互访问。后来,人们将可实现虚拟化的软件、硬件和固件统称为VMM或Hypervisor。[19]
  7. 虚拟机是指通过虚拟机监控器在某硬件平台上模拟出的独立的、有特定指令集架构的虚拟硬件系统,虚拟机上可以运行不同的客户操作系统。[20]
  8. 虚拟机监控器是位于物理硬件和虚拟硬件之间的软件层,它运行在物理CPU的最高特权级,负责对上层运行的虚拟机进行管理,为虚拟机提供安全独立的运行环境,控制资源访问,实现不同虚拟机之间的资源隔离,完成虚拟硬件(如硬盘、CPU、内存、网卡等)与物理硬件之间的操作映射。[20]
  9. 80286与前代处理器相比,在四个方面有显著的改进:速度快;同时处理多任务;内存的实地址多达16MB;内存虚拟地址空间多达1GB(280字节)。[22]
  10. 在保护模式下,80286提供虚拟存储、多任务的软件及大容量的存储空间。之所以称为保护模式,是因为处理器对段的边界、属性和访问权等都可以自动地进行检查,通过四级保护环结构,在处理多任务时,每个程序各自分开在自己的空间运行,相互隔离。[22]
  11. 80386是80286进一步提高和发展的产物。一方面与80286一样,在实模式下向上一代兼容,另一方面扩充了80286在保护模式下的功能。80386另一个重要的改进是将32位I/O和32位寻址带给了微机。[22]
  12. 1991年,世界上第一个监控黑客行动的蜜罐程序是使用chroot来实现的,命令参数指定的根目录当时被作者戏称为“Chroot 监狱”(Chroot Jail),而黑客突破chroot限制的方法被称为“越狱”(Jailbreak)。后来,FreeBSD4.0系统重新实现了chroot命令,用它作为系统中进程沙箱隔离的基础,并将其命名为FreeBSDJail。[23]
  13. FreeBSD是一种类UNIX操作系统,是由经过BSD、386BSD和4.4BSD发展而来的Unix的一个重要分支。[24]
  14. OpenStack既是一个开源云操作系统(或云计算管理平台),也是一套laaS组件,任何人或企业都可以基于此建立和提供云端运算服务。[20]
  15. 存储空间是能够访问的内存的范围。一个数据在内存中的位置称为物理地址或绝对地址。存储空间的大小取决于内存的实际容量。[4]
  16. 一个程序可以访问的地址是有限的。一个程序可以访问的地址范围称为地址空间,也可
    以说是程序访问信息所用的地址单元的集合,这些单元的编号称为逻辑地址。[4]
  17. 寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。
广告位:底部(ad-bottom)—— 请到中台「公共区块」编辑此内容