C++-虚拟内存的大小有没有限制?
比如说对于一个32位的操作系统来说,可访问的地址空间是4G。那么如果实体内存有2G,是不是就意味着虚拟内存最多只能是2G?
如果是这样的话,那么如果实体内存有4G的话,岂不是虚拟内存无法实现了?
如果不是这样,那么如果实体内存加上虚拟内存的总大小大于4G的话,怎么用32位地址访问到这所有的地址空间?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
关于:虚拟内存,虚拟内存地址,物理内存,物理内存地址:
先说说为什么会有虚拟内存和物理内存的区别。正在运行的一个进程,他所需的内存是有可能大于内存条容量之和的,比如你的内存条是256M,你的程序却要创建一个2G的数据区,那么不是所有数据都能一起加载到内存(物理内存)中,势必有一部分数据要放到其他介质中(比如硬盘),待进程需要访问那部分数据时,在通过调度进入物理内存。所以,虚拟内存是进程运行时所有内存空间的总和,并且可能有一部分不在物理内存中,而物理内存就是我们平时所了解的内存条。有的地方呢,也叫这个虚拟内存为内存交换区。
那么,什么是虚拟内存地址和物理内存地址呢。假设你的计算机是32位,那么它的地址总线是32位的,也就是它可以寻址0~0xFFFFFFFF(4G)的地址空间,但如果你的计算机只有256M的物理内存0x~0x0FFFFFFF(256M),同时你的进程产生了一个不在这256M地址空间中的地址,那么计算机该如何处理呢?回答这个问题前,先说明计算机的内存分页机制。
计算机会对虚拟内存地址空间(32位为4G)分页产生页(page),对物理内存地址空间(假设256M)分页产生页帧(page frame),这个页和页帧的大小是一样大的,所以呢,在这里,虚拟内存页的个数势必要大于物理内存页帧的个数。在计算机上有一个页表(page table),就是映射虚拟内存页到物理内存页的,更确切的说是页号到页帧号的映射,而且是一对一的映射。但是问题来了,虚拟内存页的个数 > 物理内存页帧的个数,岂不是有些虚拟内存页的地址永远没有对应的物理内存地址空间?不是的,操作系统是这样处理的。操作系统有个页面失效(page fault)功能。操作系统找到一个最少使用的页帧,让他失效,并把它写入磁盘,随后把需要访问的页放到页帧中,并修改页表中的映射,这样就保证所有的页都有被调度的可能了。这就是处理虚拟内存地址到物理内存的步骤。
现在来回答什么是虚拟内存地址和物理内存地址。虚拟内存地址由页号(与页表中的页号关联)和偏移量组成。页号就不必解释了,上面已经说了,页号对应的映射到一个页帧。那么,说说偏移量。偏移量就是我上面说的页(或者页帧)的大小,即这个页(或者页帧)到底能存多少数据。举个例子,有一个虚拟地址它的页号是4,偏移量是20,那么他的寻址过程是这样的:首先到页表中找到页号4对应的页帧号(比如为8),如果页不在内存中,则用失效机制调入页,否则把页帧号和偏移量传给MMC(CPU的内存管理单元)组成一个物理上真正存在的地址,接着就是访问物理内存中的数据了。总结起来说,虚拟内存地址的大小是与地址总线位数相关,物理内存地址的大小跟物理内存条的容量相关。
读这篇文章
Pushing the Limits of Windows: Virtual Memory
对于 32 位的操作系统来说,最大的访问空间是 4G,但是操作系统要使用物理内存还是硬盘内存,是由操作系统决定的。
对于物理内存有2G的时候,并不是说虚拟内存最大只能是 2G,可以更多,怎么使用时操作系统的事情。
即使物理内存有 4G,操作系统还是有可能在硬盘上分配虚拟内存。
虚拟内存的使用是对用户透明的,让我们看起来整个内存空间就是一块连续的内存,有时候操作系统可能为了分配连续空间,或者根据访问频率,根据虚拟内存的交换原则,即使还有物理内存,但也有可能使用虚拟内存。
没有限制,虚拟内存会往辅助存储器上扩展(例如:磁盘),而且,即使你的内存只有2G,也不会把全部的2G都给虚拟内存,还要留一部分给操作系统内核呢,也就是说,虚拟内存的4G空间有以下两部分组成:(小于2G的内存m) + (4G-m的辅存),两者之间会进行页交换,如此来实现虚拟内存!
32位的系统就是4G的虚拟地址空间,而且可以全部访问。虚拟内存会把硬盘的一部分划分出来作为物理内存的交换区,如果物理内存不够用了,就会把物理内存中一些可以替换的旧的页换到硬盘中去,将新的内容分配新的可用的虚拟地址并加载到物理内存中。这个特点也是虚拟内存的主要作用。
可以看一下这篇blog:
虚拟内存介绍
楼主弄错了基本概念,将操作系统中虚拟内存的概念和windows系统中虚拟内存的概念弄混了。操作系统中虚拟内存的概念是,就算你只有2G的内存,那么每个进程(不管多少个进程)能访问的空间是4G,这种技术叫做虚拟内存。windows中的“虚拟内存”指的是交换空间的大小。两个概念不一样。楼主的虚拟内存指的是交换空间。
如果内存有4G,你同时要运行多个进程(设为两个),每个进程需要访问的空间都是4G(一般进程不会那么大),这样子交换空间的大小随便就需要4G,加上你内存的4G,每个进程都有一部分在交换空间中,操作系统负责不停的交换空间的大小和虚拟内存(通常这会严重降低程序性能)。
补充下楼上几位没有提到的地方。
对于32位系统,大多数操作系统都会将4GB的内存空间的一部分挪给内核使用,应用程序无法直接访问这一段内存,这部分内存空间称为内核空间。Windows默认情况下会将高地址的2GB分配给内核(也可配置为1GB),而Linux默认情况下将高地址的1GB空间分配给内核。
参考阅读:《程序员的自我修养—链接、装载与库》第10章--内存
Linux进程地址空间分布图]:
windows进程地址空间分布图:
LZ混淆了概念
虚拟内存的大小和你计算机物理内存的大小没关系。只和总线宽度有关系。
比如你说的情况。物理内存只有2G。那虚拟内存一样会有4G。虚拟内存和物理内存只是映射关系。物理内存上的一个块可能被好几个虚拟地址指向。这个映射表存在mmu之中。可以绝对这个虚拟地址对应的物理内存是哪一块。
对于虚拟内存加上物理内存大于4G。这个不是一个概念的东西,没办法相加的。从名字上可以直观看出,虚拟内存就是虚拟的。主要是用来描述程序的。就是一个程序给你4G的空间可以用(其实是有1G或者2G是没办法访问的,是操作系统代码区)。通过这个地址可以映射到物理内存上。当物理内存小于虚拟内存时。程序运行时就会页替换发生的次数就会很多。(因为程序运行时,并不要求一次性把所有的都加载进内存,当发生要访问的不在内存时,会发生缺页中断。然后去硬盘上调)。额。。好吧,我说的不是很清楚,LZ想更明白更系统的话,推荐看看深入理解计算机系统第九章。看完之后应该很清晰明了了
--------回答LZ在评论里问的问题的补充------------------
虚拟内存不一定是存在的,就好像堆的这个概念,其实就是虚拟内存,好像操作系统再说。这块内存你用吧。随便用,非常大。让每个进程产生自己真的有那么大内存的错觉。但并不是真的就分配了那么大给他。只是在new的时候才会分配真正的内存。这个new的过程也建立了虚拟地址和物理地址的映射