有关虚存

stonefire21 2006-03-14 03:33:12
假如CPU的访存可达4G,操作系统利用虚存去管理,并将近期不用的空间换出到外存上,每个进程所看到的都有4G存储空间,请问所有进程实际上已经分配的空间,包括内存和辅存的空间,加起来是不是可以超过4G这个范围?举个例子来说,假如虚存上划定1G为系统区,3G为用户区,现在有3个进程并发运行,这3个进程在用户区都需要占满了属于自己的3G空间才能运行(只是个假设,为了提出问题),那么此时系统总分出去的存储空间,不管是物理空间还是换出的空间,加起来可以超过4G呢?
...全文
170 点赞 收藏 11
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
hhuchina 2006-05-26
好贴
回复
bluedreammer 2006-05-26
32位机器当然只能寻址4G内存空间。但并不表示不支持4G以上的物理空间。

linux2.4版本上的内核在32位cpu(需要cpu支持PAE,可以实现内存3级分页)上也是支持4G以上的大内存的。可在make menuconfig -> Process type and feature -> High Memory Support里面选择。

其解释也是非常的清楚。不妨大家看看
回复
tb01412 2006-03-17
LZ的理解与我的理解基本上一致了
略有不同之处:
1.x86的linux内核最大映射892M内存指的是在启动起来后就映射好了的,但它还可以在运行过程中去扩展内存映射,也就是说具备管理大于892M物理内存的能力。

2.我装的是REDHAT 9.0,里面只能划分512M交换分区,我好像记起来了,交换分区的最大大小是物理内存的两倍,不知你的机子内存是1G吗?所有的进程共享指定大小的交换分区,操作系统在理论上是可以使用超过4G大小的虚拟空间的,假定交换分区可以做到无限大,那么内核在理论上就可以做到管理远大于4G的虚存空间的,仅会受到对管理交换分区的一些变量本身能寻址的大小的限制,但就目前来看,内核对交换分区的管理最大可能性也仅支持4G(因为对交换分区的管理部分代码中大量使用了整形变量来寻址),所以加起来也不过就是8G空间

3.你最先的假定是3个4G的进程,如果进程间完全没有共享内存的话,并且每个进程都把自己所有代码加载进了内存,我想这在理论上都行不通了
回复
stonefire21 2006-03-17
应该说,tb01412的回答已经很详细了,且并没有回避问题的实质。我谈谈我的理解,不知道我的理解恰当否。
一、一般情况下,x86的linux内核最大映射892M内存,最多使用外存上512M交换空间。不过这512M交换空间是针对每个进程来说的呢,还是总共的数字?(也就是每个进程都有各自最大512M的外存交换空间呢,还是所有进程总共就只能在512M空间里面杯割呢)根我查阅,RedHat linux的swap交换区最大可以划定磁盘上的2G,这又怎样解释呢?
二、在你回答中的第一至三点其实都强调:由于硬件的原因,CPU的访存能力会受到限制,如4G。我也从来没有否认这一点。但是,这4G空间是针对每一个进程来说的,譬如:内核可以看到的虚存空间有4G,这个不假;进程A可以看到的虚存空间也有4G,当然有一部分是没有访问权限的,这个也没错;进程B,进程C.....,各自的虚存范围也是4G。
我的问题是:当操作系统将一部分的物理内存空间交换到外存上面去的时候,此刻物理内存上所有已分配出去的物理空间,加上外存交换区上已经分配出去用作暂存的空间(此刻正保存某些进程的一部分虚存空间)的那一部分空间,理论上可不可以超过4G。注意,我这里是指已分配给所有的进程的空间,并不是单就某个进程来说的。
而你的例子,也已经指出:理论上是存在这样的一个可能性。容我再述一次:某系统有4G物理内存,划定外存上512M作为交换空间,某时刻有三个进程,每个进程均需要占用独自的(而不是共享的那一部分)1.4G的物理内存才能运行。那么此进3*1.4=4.2已经大于4G空间了(但少于4G+512M)。而如果果如你断言的那样,系统能正常运行,那么就已经说明系统为所有进程分配的空间(物理上的加上缓存在外存上的)可以超过4G。例子中,操作系统只是轮流地将处于睡眠状态的两个进程的一些空间换出去外存上面,而为此刻将被唤醒的那个进程腾出1.4G使之具备运行的条件,进而转入运行态而已。
回复
可以超过4G,因为我们通过据说的4G的空间不包括共享vm_area_struct内存区域
回复
nancygreen 2006-03-15
好精彩:)  
mark
回复
tb01412 2006-03-15
再补充一点:
如果你有4G的物理内存,512M交换空间,有三个进程,每个进程占用1.4G,那么内核在理论上可以让你的三个进程完全跑起来的,在操作系统上跑的所有进程所需的空间再加上操作系统本身所占的空间总和不能大于物理空间与交换空间的总和(假定每个进程都不共享内存空间,包括动态库等,并且每个进程的所有代码都会调入到内存去执行,之所以有这个假设,是因为一个可执行程序并不一定都会把它所有部分内部都调入到内存去的,比如你在那个程序中写了很多无用的函数,操作系统在调度你运行的时候,并不会一次性将这个文件所有内容调入内存,会按一定算法按需调入)
回复
tb01412 2006-03-15
一、在x86的linux上,内核只会映射892M的内存,最多仅用512M交换空间:
内核在通常情况下只映射892M内存,大于892M以上的地址空间被称为高端地址,需要临时映射,具体请参见<<LINUX内核设计与实现>>一书的关于内存管理的章节。
最多仅使用512M交换空间,不知你安装了LINUX的发行版了没有?因为在LINUX内核设计的时候,那些写内核的人认为如果使用多于512M的交换空间,不会带来多少好处,而会影响效率,所以就认为512M是个相对的限制。如果你的进程非得要使用2G左右的内存,而物理内存又比较大,内核会帮你完成高端地址的映射。但是你非得要使用大于4G的内存,那么很不幸,内核无法帮你办到,因为CPU的MMU是按32位进行寻址的,没有硬件的帮助,你能访问到大于32位所表示的内存地址上去吗????

二、我说的是一种假设,也是一种极端情况,不过不可能出现这样的情况

三、CPU的寻址与外围的IO寻址是有区别的,CPU的指令寻址,如果是32位,那么就算编译器是基于64位的,把你的代码也编译成了64位寻址方式,那么CPU解码的时候,还是会取四个字节去解码,还是按三十二位的方式来运行,这时有可能就出现了指令异常。而对外围设备的寻址,在X86上,是16位IO方式,不知你做过驱动没有?我们做一个比方:你用什么方法可以实现大数表示法?当然可以用数组的方式来表示一个很大的数啊,对外围设备的管理也同样可以如此,我不可以用两个整形数来表示一个大于4G的东东吗??
此时,你可能要问,既然外围设备可以这样做,那为何我的程序不可以这样做呢??呵呵,那就是因为CPU的寻址能力的问题了(CPU需要去取内存中的某个地址的内容,然后解码,然后执行),关键就在这里,在32位CPU上是按4个字节进行的,它不会智能到像你程序那样把两个字节合起来再解码!!!!!!你的程序可以访问大于4G的数据文件,可以使用大于4G的数据,但是你的某个函数的地址绝不能大于4G,编译器也绝不会让你的程序里产生大于4G的逻辑地址(包括变量地址,函数地址,大于4G的数组)。你当然可以使用大于4G的数据文件,比如你开一个100M的缓冲区,并从那个大于4G的文件中读数据,你读完一次,就丢一次,这是可以的,你也可以动态分配空间,每次分配不大于4G的空间(理论上是允许的,你分配较大的空间时,就有可能把不用的数据交换到了交换分区中去了),但绝对不允许你一次就分配大于4G的空间(从理论上说就不允许)


总之,当涉及到CPU寻址的时候,就绝不能超过4G的限制,编译器这关你就过不了!!!!!
你可以读取大于4G的文件,处理大于4G的数据,但你的代码段,数据段,BSS段的空间总和绝不对超过4G
回复
stonefire21 2006-03-15
谢谢tb01412的回答。但这个回答还是不能使我觉得问题已经很好的解决了,反而更迷惑。
一、按你的意思,在x86的linux上,内核只会映射892M的内存,最多仅用512M交换空间。请找出具体的依据出来说明。进一步推论,虽然一个系统为进程提供了4G的虚拟空间,但实际上还是划定了一个限制,进程能够使用的空间远少于4G。但假如一个进程真的要用4G的空间,这个时候OS应该如何收拾呢?(是不是需要“专门的内核函数进行映射”才能处理呢?但如果我的计算机配置256M内存,那加上最多的512交换空间,还是远远少于4G哦?)
二、如果三个进程都使用了3G虚存空间,你认为归属于三个不同进程、抽象上不同的3G虚存空间实质上是被操作系统映射到相同的3G物理内存上面。但必须要看到,三个进程的3G虚存的内容不一定一致的,怎么可以盲目的都映射到相同的物理空间上呢?
三、你的回答犯了一些错误,诚然,CPU一个字的大小和系统总线确定了OS可以管理的内存的能力(如4G),但是,为什么我们现在用的操作系统可以看到磁盘上几十G,上百G的空间呢,这是因为有一个映射的机制。OS完全可以将需要换出的内存空间放在大至几十G的磁盘上的一个文件上,只要OS有记录,知道那部分内存的内容放在哪里就行了。这样岂不是对上来说提供了内存的访问速度,对下来说提供了磁盘的容量么?
回复
yjf7888 2006-03-15
关注
回复
tb01412 2006-03-14
在32位的X86上,无论是内核还是在用户一级,都不能访问到4G以外的空间,这就是由寻址范围所决定的,况且,在基于X86的LINUX上,只会映射892M物理内存空间,高端内存需要专门的内核函数进行映射,最多仅使用512M交换空间。
有一种极端情况发生:就是三个进程都使用了3G虚存空间,而这3G虚存空间实际是上共享的3G物理内存间,在机子上刚好就插了4G的内存条,这时在理论是通得过的!!!
在支持32位总线,32位CPU的机子上,主板最多支持4G的物理内存,这同样是由总线所决定的!!!!所以你的假设都是行不通的
回复
相关推荐
发帖
Linux_Kernel
创建于2007-08-27

4153

社区成员

Linux/Unix社区 内核源代码研究区
申请成为版主
帖子事件
创建了帖子
2006-03-14 03:33
社区公告
暂无公告