虚拟内存与物理内存的地址映射解析
物理内存与虚拟内存(虚拟地址)的区别有哪些

物理内存与虚拟内存(虚拟地址)的区别有哪些在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单元给以一个唯一的存储器地址,称为物理地址(Physical Address),又叫实际地址或绝对地址。
,店铺为大家介绍一下物理内存与虚拟内存(虚拟地址)的区别,供大家参考!物理内存与虚拟内存(虚拟地址)的区别1、应用中的概念。
物理内存,在应用中,自然是顾名思义,物理上,真实的插在板子上的内存是多大就是多大了。
看机器配置的时候,看的就是这个物理内存。
虚拟内存,这个概念就要稍微了解一下CPU了,^_^,只是稍微,毕竟我们现在谈的是应用中的概念。
我们应该知道,对于一般的32位CPU,有32根地址线,那么它的寻址空间就是4GB。
也就是说,如果没有其他的限制,我们的主板上最大可以安装4GB的物理内存。
哈哈,一般的机器是不会装那么多物理内存的,大把的银子啊,性价比可合不上。
程序员可不管这个,我们对CPU编程,不能一台机器根据你物理内存的大小我编一个程序吧?那也太原始社会了吧。
所以程序员都是直接使用的4GB的奢侈的进程空间(或许,不应该用奢侈这么短视的词。
曾几何时,128M的物理内存也是我们不可想象的呢?)。
这怎么办?总不能不用那些程序了吧。
好吧,这个问题交给OS去解决吧。
这样,OS就提出了一个虚拟内存的概念。
就是进程、用户、不必考虑实际上物理内存的限制,而直接对4GB的进程空间进行寻址。
如果所寻址的数据实际上不在物理内存中,那就从“虚拟内存”中来获取。
这个虚拟内存可以是一个专门文件格式的磁盘分区(比如linux下的swap分区),也可以是硬盘上的某个足够大的文件(比如win下的那个i386文件,好像是这个名字)。
物理内存中长期不用的数据,也可以转移到虚拟内存中。
这样的交换由OS来控制,用户看起来就好像物理内存大了一样。
有了虚拟内存的概念,我们就可以自由的使用4GB的进程空间了。
但是,前提是你的硬盘由足够的空间,而且你舍得划分出(4GB-物理内存)大的虚拟内存空间来。
物理内存和虚拟内存

物理内存和虚拟内存物理内存和虚拟内存概念物理内存:物理内存(Physical memory)是相对于虚拟内存⽽⾔的。
物理内存指通过物理内存条⽽获得的内存空间。
虚拟内存:相对于物理内存,在linux下还有⼀个虚拟内存的概念,虚拟内存就是为了满⾜物理内存的不⾜⽽提出的策略,它是利⽤磁盘空间虚拟出的⼀块逻辑内存,⽤作虚拟内存的磁盘空间被称为交换空间(Swap Space)说明作为物理内存的扩展,linux会在物理内存不⾜时,使⽤交换分区的虚拟内存,更详细的说,就是内核会将暂时不⽤的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以⽤于其它⽬的,当需要⽤到原始的内容时,这些信息会被重新从交换空间读⼊物理内存。
linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利⽤,内核会在适当的时候将物理内存中不经常使⽤的数据块⾃动交换到虚拟内存中,⽽将经常使⽤的信息保留到物理内存。
系统把物理内存中的⼀部分空间释放出来,以供当前运⾏的程序使⽤。
那些被释放的空间可能来⾃⼀些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运⾏时,再从Swap分区中恢复保存的数据到内存中。
这个swap交换区是从硬盘中预先划分⼀定的空间,所以使⽤swap交换区就需要在硬盘和内存间读写,增加IO,影响系统性能。
补充要深⼊了解linux内存运⾏机制,需要知道下⾯提到的⼏个⽅⾯:⾸先,Linux系统会不时的进⾏页⾯交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不⽤的内存页⾯。
这可以避免等待交换所需的时间。
其次,linux进⾏页⾯交换是有条件的,不是所有页⾯在不⽤时都交换到虚拟内存,linux内核根据”最近最经常使⽤“算法,仅仅将⼀些不经常使⽤的页⾯⽂件交换到虚拟内存,有时我们会看到这么⼀个现象:linux物理内存还有很多,但是交换空间也使⽤了很多。
浅析物理内存和虚拟内存的区别

浅析物理内存和虚拟内存的区别首先,我们先简单理解一下而这之间概念区别:物理内存: 值通过物理内存条而获得的内存空间,是计算机上最重要的资源之一,从本质来说,物理内存是代码和数据在其中运行的窗口,物理内存是和cpu实现交互的重要硬件设备.虚拟内存: 与物理内存相反,是指根据系统需要从硬盘中虚拟的划出一部分存储空间,是一种计算机系统的管理技术,数据计算机的程序.下面将进行详细的介绍:物理内存的作用: 计算机运行时为操作系统和各种程序提供临时的存储作用,而这种存储是没有写入硬盘的,在计算机关机后就会丢失.首先,内存会从cpu获得需要查找到某个数据的指令,然后根据存储的位置信息,去找到数据存放的真实位置,这个过程式寻址, 对于电脑系统而言,找出这个地方时还必须确定是否位置正确,因此电脑还必须判读该地址的信号,横坐标有横坐标的信号(也就是RAS信号,Row Address Strobe)纵坐标有纵坐标的信号(也就是CAS信号,Column Address Strobe),最后再进行读或写的动作。
每次访问一个地址都时需要将逻辑地址翻译为真实的物理地址,所有的程序都时共享一个物理内存,这需要每个进程将自己目前需要的资源的虚拟地址映射到真实的物理内存上去,,进程需要知道那些地址空间是在内存上,那些在磁盘中,还要记录具体数据资源的存储位置,这些都记录在页表中,当一个进程需要访问资源寻找数据的时候,就会访问页表,查找对应的映射表,如果发现资源不在页表上,就会发生缺页异常,,缺页异常的处理过程, 操作系统立即阻塞该进程,并将硬盘里对应的页换入内存,然后使该进程就绪,如果内存已经满了,没有空地方了,那就找一个页覆盖,至于具体覆盖的哪个页,就需要看操作系统的页面置换算法.置换算法发生后,os会从物理内存中再配一个物理页,然后将该”缺页”从磁盘中读到内存中,再设置缺页的虚拟页,和物理页的映射关系,,这样程序才会继续运行下去, 但是很明显的一点是,当操作系统捕获到缺页错误时,它应知道程序当前所需要的页在可执行文件中的哪一个位置。
虚拟内存技术的工作原理

虚拟内存技术的工作原理虚拟内存是一种操作系统提供的一种技术,它将主存和辅助存储器(通常是硬盘)结合起来,为进程提供了一个比实际物理内存更大的地址空间。
虚拟内存技术的核心原理是将进程的逻辑地址空间与物理内存进行映射,使得进程能够访问超出实际物理内存大小的数据。
虚拟内存的工作原理可以分为几个关键步骤:1.地址转换:当进程执行时,它使用的是虚拟地址。
这些虚拟地址需要被转换为物理地址,才能在实际的物理内存中进行访问。
操作系统通过硬件机制(如页表)来进行地址转换。
2.页面调度:当进程需要访问的页面不在物理内存中时,操作系统需要将该页面从辅助存储器(硬盘)加载到物理内存。
为了提高效率,操作系统会将物理内存空间划分为固定大小的页面,这些页面是虚拟内存和物理内存之间的基本单位。
3.页面置换:当物理内存不足时,操作系统需要将一些不常用的页面从物理内存中置换出去,而将需要访问的页面置换到物理内存中。
常见的页面置换算法有FIFO(先进先出)、LRU(最近最久未使用)等。
4.页面写入:当需要写入页面数据时,操作系统可以选择将页面直接写入辅助存储器,而不是每次都写回物理内存。
这样可以减少对物理内存的访问次数,提高效率。
1.扩展了物理内存大小:虚拟内存将进程的逻辑地址空间与实际物理内存分离,使得进程可以拥有比实际物理内存更大的地址空间。
这意味着即使物理内存大小有限,进程仍然可以处理更大的数据集。
2.提高了内存利用率:由于虚拟内存将进程的逻辑地址空间与物理内存进行映射,操作系统可以根据进程的需求动态地将页面放入或置换出物理内存。
这样可以更灵活地利用物理内存,提高内存利用率。
1.频繁的页面置换可能导致性能下降:当物理内存不足时,无法避免进行页面置换操作。
如果页面置换过于频繁,会导致系统性能下降,因为频繁的磁盘访问速度远远慢于内存访问速度。
2.增加了一些开销:虚拟内存技术需要额外的硬件支持和软件机制,这会增加了一些开销。
例如,需要维护页表来进行地址转换,需要进行页面的加载和置换等操作,这些都需要消耗一定的计算资源和时间。
虚拟地址和物理地址的区别和联系

虚拟地址和物理地址的区别和联系CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分,如果CPU没有MMUMemory Management Unit,内存管理单元,或者有MMU但没有启用,CPU核在取指令或访问内存时发出的地址将直接传到CPU芯片的外部地址引脚上,直接被内存芯片以下称为物理内存,以便与虚拟内存区分接收,这称为物理地址Physical Address,以下简称PA,如下图所示。
如果CPU启用了MMU,CPU核发出的地址将被MMU截获,从CPU到MMU的地址称为虚拟地址Virtual Address,以下简称VA,而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将虚拟地址映射成物理地址,如下图所示。
MMU将虚拟地址映射到物理地址是以页Page为单位的,对于32位CPU通常一页为4K。
例如,虚拟地址0xb700 1000~0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框Page Frame。
物理地址physical address用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。
——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样。
所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一对应,也是可以接受的。
也许错误的理解更利于形而上的抽像。
虚拟内存virtual memory这是对整个内存不要与机器上插那条对上号的抽像描述。
它是相对于物理内存来讲的,可以直接理解成“不直实的”,“假的”内存,例如,一个0x08000000内存地址,它并不对就物理地址上那个大数组中0x08000000 - 1那个地址元素;之所以是这样,是因为现代操作系统都提供了一种内存管理的抽像,即虚拟内存virtual memory。
虚拟地址和物理地址转换

虚拟地址和物理地址转换参考如下虚拟地址虚拟地址空间虚拟地址并不真实存在于计算机中。
每个进程都分配有自己的虚拟空间,而且只能访问自己被分配使用的空间。
理论上,虚拟空间受物理内存大小的限制,如给有4gb内存,那么虚拟地址空间的地址范围就应该是0x00000000~0xffffffff4gb。
为什么每个进程的虚拟地址空间范围会这么大?这涉及地址映射机制;当程序实际运行时,系统将首先将虚拟地址映射到物理地址中的范围。
另外一个概念:虚拟内存。
虚拟内存是内存中的一片连续地址空间。
在物理存储位置上的意义,不一定就是指物理内存,可能也是在硬盘上开辟的一篇地址空间。
物理地址物理地址用于内存芯片级的单元寻址,与处理器和cpu连接的地址总线相对应。
--这个概念应该是这些概念中最容易理解的,但值得一提的是,虽然物理地址可以直接理解为插入机器上的内存本身,但内存可以被视为一个从0字节到最大空容量逐字节编号的大数组,然后该数组被称为物理地址,实际上,它只是一个由硬件提供给软件的映像,内存不是以这种方式寻址的。
因此,更恰当的说法是“与地址总线相对应”。
然而,无论物理内存的寻址模式如何,都可以将物理地址逐个直接对应到物理内存。
也许错误的理解更有利于形而上学的抽象。
虚地址到物理地址的转换过程MVA修改的虚拟地址,由CPU#1生成step1.通过ttbr找到粗表描述符转换表基址#2+MVA的厚页表索引=厚页表的物理地址step2.通过粗表描述符找到小页描述符粗页表基址#3+MVA的小页表索引=小页表的物理地址step3.通过小页描述符找到物理地址小页面基址的页面索引#4+MVA=物理地址step1得到的粗页表的物理地址位定义步骤2中获得的小页表的物理地址位定义step3得到的物理地址位定义注1:严格来说,该地址可能由FCSE或ARM926EJ-S处理器生成注2:转换表基地址保存在ttbr,详见ttbr注3:厚页表的基址保存在厚页表描述符中。
虚拟内存与内存映射:操作系统中的重要概念

虚拟内存与内存映射:操作系统中的重要概念虚拟内存与内存映射是操作系统中非常重要的概念,它们在计算机系统中的内存管理中扮演着重要的角色。
首先,我们来了解一下虚拟内存。
虚拟内存是一种计算机系统中的内存管理技术,它将计算机的物理内存和硬盘空间结合起来,使得操作系统可以为每个进程提供一个私有的虚拟地址空间。
虚拟内存的使用可以让每个进程都感觉自己独占整个计算机的物理内存,而不需要考虑其他进程的存在。
虚拟内存的工作原理基于分页机制。
操作系统将进程的虚拟地址空间分成一个个固定大小的页面,通常是4KB或者8KB。
同时,物理内存也被划分为与虚拟页面相同的大小的物理页面。
当进程需要访问一个特定的虚拟地址时,操作系统会将这个虚拟地址翻译成对应的物理地址,然后将物理地址提供给硬件进行访问。
如果所需的物理页面在物理内存中已经存在,则直接将物理地址提供给硬件;如果所需的物理页面不在物理内存中,则需要将一个不再使用的物理页面选择出来,把其内容写入硬盘中的交换空间(swap space),然后将所需的物理页面从硬盘中加载到物理内存中,然后再提供给硬件。
这个过程也被称为页面置换(page swapping)。
虚拟内存的优点主要包括以下几点:1.扩充了可用的内存空间:虚拟内存允许每个进程有一个大的虚拟地址空间,使得每个进程都可以感觉自己独占整个计算机的物理内存。
这样,即使计算机的物理内存有限,也能够运行更多的进程。
2.提高了内存的利用率:虚拟内存可以通过页面置换机制将内存中不再使用的页面写入硬盘,从而释放出内存空间供其他进程使用。
这使得物理内存的利用率更高,减少了内存浪费。
3.简化了程序的编写:虚拟内存将物理内存和硬盘空间结合起来,对程序员来说,无需关心物理内存的具体情况,只需要在虚拟地址空间中进行内存访问操作就好。
这样,程序员可以将精力更多地集中在程序的逻辑实现上,而不需要过多关注内存管理的细节。
内存映射是虚拟内存的一个重要概念。
物理内存、页面文件、交换区和虚拟内存

物理内存、页⾯⽂件、交换区和虚拟内存物理内存,顾名思义,就是实实在在存在的那个东西,插在你电脑主板上的内存条所提供的空间。
页⾯⽂件,这个是硬盘上的⼀块空间,在Windows下表现为⼀个⽂件。
这个页⾯⽂件存在的意义就是在物理内存被占⽤满以后,将物理内存中的东西移动到硬盘上的这个空间,腾出物理内存给需要的应⽤程序来使⽤。
交换区,这个是物理内存和页⾯⽂件空间的总和,“交换”的含义,则是指在硬盘⽂件、CPU和其它IO之间进⾏数据的传递和暂存(这句话对于了解计算机运⾏基本流程的⼈来说应该可以理解)。
虚拟内存,这个概念恐怕是⽬前为⽌最为含混不清的⼀个东西了,会有很多种不同的含义。
在这⾥,我先说⼀下在⼀个程序猿眼中的虚拟内存是个啥。
很显然,这个世界上的电脑配置是五花⼋门,可⽤的物理内存数量也是分为很多等级的。
作为⼀个苦逼的程序猿,我们不可能在考虑程序逻辑的时候还要去考虑客户的机器有多少内存可以⽤,也不可能去详细调查实际的物理内存地址是多少到多少,好在OS会为我们完成这些⼯作。
每⼀个运⾏的进程,都会获得⼀个 4G的内存地址空间,这就是所谓的虚拟内存,这⾥⾯的所有地址都是虚拟的,和物理内存啥的并不直接挂钩。
⽽在操作系统那头,这些虚拟地址所映射到的实际地址,可以是物理内存地址,也可以是页⾯⽂件的地址。
如果是物理内存⼩于这个虚拟地址的范围的话,映射的物理内存还可能是重复的物理内存地址⽚段,使⽤的时候可以通过清空内存数据,将内存数据写⼊页⾯⽂件这样的⽅式进⾏物理内存的重新利⽤,以提⾼物理内存的利⽤效率。
⽽不少⼈,尤其是对Windows刚有所了解的⼈,所理解的虚拟内存,往往是指页⾯⽂件。
这也是微软的意见,他们在⾃⼰的操作系统中就是这么写的,见下图:⽽在Aida64,或者说是曾经的Everest中,虚拟内存是交换区 + 物理内存 = 物理内存 * 2 + 页⾯⽂件。
⽼实说,我并没有理解这个的概念是什么。
其实上述虚拟内存的说法都没有什么问题,都是约定俗成的说法,关键是要搞清楚什么时候的“虚拟内存”是指什么,概念不混淆就可以。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在进入正题前先来谈谈操作系统内存管理机制的发展历程,了解这些有利于我们更好的理解目前操作系统的内存管理机制。
一早期的内存分配机制
在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。
当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。
那当程序同时运行多个程序时,操作系统是如何为这些程序分配内存的呢?下面通过实例来说明当时的内存分配方法:
某台计算机总的内存大小是128M,现在同时运行两个程序A和B,A需占用内存10M,B需占用内存110。
计算机在给程序分配内存时会采取这样的方法:先将内存中的前10M分配给程序A,接着再从内存中剩余的118M中划分出110M分配给程序B。
这种分配方法可以保证程序A和程序B都能运行,但是这种简单的内存分配策略问题很多。
图一早期的内存分配方法
问题1:进程地址空间不隔离。
由于程序都是直接访问物理内存,所以恶意程序可以随意修改别的进程的内存数据,以达到破坏的目的。
有些非恶意的,但是有bug的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。
这种情况对用户来说是无法容忍的,因为用户希望使用计算机的时候,其中一个任务失败了,至少不能影响其它的任务。
问题2:内存使用效率低。
在A和B都运行的情况下,如果用户又运行了程序C,而程序C需要20M大小的内存才能运行,而此时系统只剩下8M的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来
供程序C使用,然后再将程序C的数据全部装入内存中运行。
可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。
问题3:程序运行的地址不确定。
当内存中的剩余空间可以满足程序C的要求后,操作系统会在剩余空间中随机分配一段连续的
20M大小的空间给程序C使用,因为是随机分配的,所以程序运行的地址是不确定的。
二分段
为了解决上述问题,人们想到了一种变通的方法,就是增加一个中间层,利用一种间接的地址访问方法访问物理内存。
按照这种方法,程序中访问的内存地址不再是实际的物理内存地址,而是一个虚拟地址,然后由操作系统将这个虚拟地址映射到适当的物理内存地址上。
这样,只要操作系统处理好虚拟地址到物理内存地址的映射,就可以保证不同的程序最终访问的内存地址位于不同的区域,彼此没有重叠,就可以达到内存地址空间隔离的效果。
当创建一个进程时,操作系统会为该进程分配一个4GB大小的虚拟进程地址空间。
之所以是4GB,是因为在32位的操作系统中,一个指针长度是4字节,而4字节指针的寻址能力是从
0x00000000~0xFFFFFFFF,最大值0xFFFFFFFF表示的即为4GB大小的容量。
与虚拟地址空间相对的,还有一个物理地址空间,这个地址
空间对应的是真实的物理内存。
如果你的计算机上安装了512M大小的内存,那么这个物理地址空间表示的范围是
0x00000000~0x1FFFFFFF。
当操作系统做虚拟地址到物理地址映射时,只能映射到这一范围,操作系统也只会映射到这一范围。
当进程创建时,每个进程都会有一个自己的4GB虚拟地址空间。
要注意的是这个4GB的地址空间是“虚拟”的,并不是真实存在的,而且每个进程只能访问自己虚拟地址空间中的数据,无法访问别的进程中的数据,通过这种方法实现了进程间的地址隔离。
那是不是这4GB的虚拟地址空间应用程序可以随意使用呢?很遗憾,在Windows系统下,这个虚拟地址空间被分成了4部分:NULL指针区、用户区、64KB 禁入区、内核区。
应用程序能使用的只是用户区而已,大约2GB左右(最大可以调整到3GB)。
内核区为2GB,内核区保存的是系统线程调度、内存管理、设备驱动等数据,这部分数据供所有的进程共享,但应用程序是不能直接访问的。
人们之所以要创建一个虚拟地址空间,目的是为了解决进程地址空间隔离的问题。
但程序要想执行,必须运行在真实的内存上,所以,必须在虚拟地址与物理地址间建立一种映射关系。
这样,通过映射机制,当程序访问虚拟地址空间上的某个地址值时,就相当于访问了物理地址空间中的另一个值。
人们想到了一种分段(Sagmentation)的方法,它的思想是在虚拟地址空间和物理地址空间之间做一一映射。
比如说虚拟地址空间中某个10M大小的空间映射到物理地址空间中某个10M大小的空间。
这种思想理解起来并不
难,操作系统保证不同进程的地址空间被映射到物理地址空间中不同的区域上,这样每个进程最终访问到的
物理地址空间都是彼此分开的。
通过这种方式,就实现了进程间的地址隔离。
还是以实例说明,假设有两个进程A和B,进程A所需内存大小为10M,其虚拟地址空间分布在0x00000000到
0x00A00000,进程B所需内存为100M,其虚拟地址空间分布为
0x00000000到0x06400000。
那么按照分段的映射方法,进程A在物理内存上映射区域为0x00100000到0x00B00000,,进程B在物理内存上映射区域为0x00C00000到0x07000000。
于是进程A和进程B分别被映射到了不同的内存区间,彼此互不重叠,实现了地址隔离。
从应用程序的角度看来,进程A的地址空间就是分布在
0x00000000到0x00A00000,在做开发时,开发人员只需访问这段区间上的地址即可。
应用程序并不关心进程A究竟被映射到物理内存的那块区域上了,所以程序的运行地址也就是相当于说是确定的了。
图二显示的是分段方式
的内存映射方法。
图二分段方式的内存映射方法
这种分段的映射方法虽然解决了上述中的问题一和问题三,但并没能解决问题二,即内存的使用效率问题。
在分段的映射方法中,每次换入换出内存的都是整个程序,这样会造成大量的磁盘访问操作,导致效率低下。
所以这种映射方法还是稍显粗糙,粒度比较大。
实际上,程序的运行有局部性特点,在某个时间段内,程序只是访问程序的一小部分数据,也就是说,程序的大部分数据在一个时间段内都不会被用到。
基于这种情况,人们想到了粒度更小的内存分割和映射方法,这种方法就是分页 (Paging)。
三分页
分页的基本方法是,将地址空间分成许多的页。
每页的大小由CPU 决定,然后由操作系统选择页的大小。
目前Inter系列的CPU支持4KB或4MB的页大小,而PC上目前都选择使用4KB。
按这种选择,4GB虚拟地址空间共可以分成1048576个页,512M的物理内存可以分为131072个页。
显然虚拟空间的页数要比物理空间的页数多得多。
在分段的方法中,每次程序运行时总是把程序全部装入内存,而分页的方法则有所不同。
分页的思想是程序运行时用到哪页就为哪页分配内存,没用到的页暂时保留在硬盘上。
当用到这些页时再在物理地址空间中为这些页分配内存,然后建立虚拟地址空间中的页和刚分配的物理内存页间的映射。
下面通过介绍一个可执行文件的装载过程来说明分页机制的实现方法。
一个可执行文件(PE文件)其实就是一些编译链接好的数据和指令的集合,它也会被分成很多页,在PE文件执行的过程中,它往内存中装载的单位就是页。
当一个PE文件被执行时,操作系统会先为该程序创建一个4GB的进程虚拟地址空间。
前面介绍过,虚拟地址空间只是一个中间层而已,它的功能是利用一种映射机制将虚拟地址空间映射到物理地址空间,所以,创建4GB虚拟地址空间其实并不是要真的创建空间,只是要创建那种映射机制所需要的数据结构而已,这种数据结构就是页目和页表。
当创建完虚拟地址空间所需要的数据结构后,进程开始读取PE 文件的第一页。
在PE文件的第一页包含了PE文件头和段表等信息,进程根据文件头和段表等信息,将PE文件中所有的段一一映射到虚拟地址空间中相应的页(PE文件中的段的长度都是页长的整数倍)。
这时PE文件的真正指令和数据还没有被装入内存中,操作系统只是根据PE文件的头部等信息建立了PE文件和进程虚拟地址空间中页的映射关系而已。
当CPU要访问程序中用到的某个虚拟地址时,当CPU发现该地址并没有相相关联的物理地址时,CPU认为该虚拟地址所在的页面是个空页面,CPU会认为这是个页错误(Page Fault),CPU也就知道了操作系统还未给该PE页面分配内存,CPU会将控制权交还给操作系统。
操作系统于是为该PE页面在物理空间中分配一个页面,然后再将这个物理页面与虚拟空间中的虚拟页面映射起来,然后将控制权再还给进程,进程从刚才发生页错误的位置重新开始执行。
由于此时已为PE文件的那个页面分配了内存,所以就不会发生页错误了。
随着程序的执行,页错误会不断地产生,操作系统也会为进程分配相应的物理页面来满足进程执行的需求。
分页方法的核心思想就是当可执行文件执行到第x页时,就为第x页分配一个内存页y,然后再将这个内存页添加到进程虚拟地址空间的映射表中,这个映射表就相当于一个y=f(x)函数。
应用程序通过这个映射表就可以访问到x页关联的y页了。
总结:
32位的CPU 的寻址空间是4G , 所以虚拟内存的最大值为4G , 而windows 操作系统把这4G 分成2 部分, 即2G 的用户空间和2G 的系统空间, 系统空间是各个进程所共享的, 他存放的是操作系统及一些内核对象等, 而用户空间是分配给各个进程使用的, 用户空间包括用: 程序代码和数据, 堆, 共享库, 栈。