鱼C论坛

 找回密码
 立即注册
查看: 7630|回复: 51

虚拟空间,物理空间

[复制链接]
发表于 2012-7-2 10:02:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
鱼油们好,有不有对虚拟空间,物理空间理解的很好的,我一直理不清这两个概念,所以想请教一下,我把我理解的和想问的写出来如下,如果我理解的不对,希望大家帮我指正,和帮助我回答我不明白的地方:

我理解的:
拿虚拟空间4G,真实内存2G举例,当物理空间不够时,硬盘的虚拟内存就开始发挥作用了。
每个程序有自己的4G虚拟空间,从0x 00000000 00000000 - 0x FFFFFFFF FFFFFFFF范围的地址,程序想用哪个地址就用哪个。
虚拟地址是为了使用灵活,每个程序的地址独立,不会和其它程序冲突。
每个时刻只会有一个线程拥有时间片。

想问的:
程序运行起来之后,可能在不断的申请释放地址,这些都是虚拟地址对吧,CPU在接收到这些地址时,到内存找它们对应的位置时,先要转换成一下真实的,那么地址转换器是怎样转换这些地址的,是有固定公式,还是随机的从真实地址的开始搜索,找到一块合适的,就将这块真实的物理地址与程序申请的这个虚拟地址对应,并且做相应的记录工作?
每个程序拥有自己独立的4G,这句话除了说程序可以从4G虚拟地址申请任意的一个地址,还表示它可以拥有所有的4G物理空间吗?比如说有两个大型的程序A和B,A程序初始化时,malloc3G空间,这时时间片到期,它退出,B程序开始初始化,它也很大型,初始化函数中有一句malloc(2G),这样3G+2G > 4G, B程序的malloc是不会成功的吧,每个程序不是都拥有4G空间,为什么B程序malloc(2G)都不能成功?
还有就是"每个时刻只会有一个线程在内存中"这句话,我一直觉得这个很关键,但又不明白它跟虚拟内存,物理内存的理解到底有什么具体的关系。

由于基础有限,大家别觉得我问的好笑,理解错的希望大家帮忙指正,非常感谢,即使不懂,但也很想弄明白这两个概念的,欢迎和我一起找资料和讨论。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-2 19:05:06 | 显示全部楼层
想明白,就自己去学windows的保护模式,这其中的关系错综复杂不是一两句能给你解释清楚的。。。就算你拿出50个鱼币,我也不见得愿意花费时间去说,况且你一个鱼币也没有就想问这么高深的问题。。。

:lol 玩笑。。。例如指令,mov eax,ds:[0x12345678]. 0x12345678也就是虚拟地址,我叫有效地址,然后
ds.base+0x12345678是线性地址,这里的ds.base不说了,说了你也无法理解,也不是一句两句能说清楚的。。。这样出来了线性地址,然后根据分页机制转换成物理地址。    每一个进程都拥有4G内存,是能寻址4G,不是拥有。。。进程切换通过cr3寄存器,这个切换过程太过复杂,也不是一两句能说清楚的。。。这个切换过程跟windows的分页机制关系特别密切。。。建议你还是去学习学习windows保护模式。。。还有一半不要再论坛上问这么高深的问题。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-2 20:01:27 | 显示全部楼层
       很久以前,程序员自己负责将需要的内容从硬盘调到内存,然后再使用。
接着,程序员烦了,于是写出了一个叫做操作系统的程序,这个程序负责将需要的内容从硬盘调到内存(当然还负责其它事情)。
       所以现在程序员不能直接操作内存地址了,程序员将虚拟地址交给操作系统,操作系统看看如何获取其内容,若有必要它会将必要的内容从硬盘载入到内存。
       操作系统的这个功能很重要,一些差的操作系统,每次程序员需要的数据,都需要从硬盘载入到内存(因为它猜不到程序员接下来要使用的数据在什么地方,而且它的运气总是很不好)。所以就有人研究了很多的算法,使得你需要的80%的数据都已经从硬盘载入到内存了。这些算法很复杂可以去看操作系统方面的书。
       操作系统的这个功能还有一个好处,就是使得运行在其上的任意程序都可以认为它“独占”了4GB内存空间,因为大不了操作系统会帮你从硬盘加载嘛。
       以上是关于虚拟内存的说明。还有"每个时刻只会有一个线程在内存中"这个话不对,在单核时代,每个时刻,只有一个线程在执行。在双核时刻,每个时刻最多可以有两个线程在执行。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-2 22:51:56 | 显示全部楼层

首先代表党中央,中国人民ZF,CCTV,……,谢谢你的回答。
看得出你对虚拟地址的原理是足够了解的,所以相信顺着你的回答理解下去,理解虚拟地址
应该是没问题的,再次感谢。

你的回答又勾引出我若干的问题,如下:
① long long ago,运行一个可执行文件不是像现在鼠标点点就行了,要程序员自己调到内存

,那程序员是怎么将要运行的程序调到内存的,现在鼠标一双击,操作系统又是怎么知道程
序在硬盘中的位置的?(看完你回答中的第一句话,想问的问题)
② 操作系统谋权但没篡位,要对内存进行什么操作时,还是由我们发出指令,但操作者是它
,其实也就是微软那些N人搞出个操作系统往那一扔,淡淡的加上一句“咯,用它你可以可方
便的操作电脑了”,从而让大多数人都停留在了操作系统之上,也让我对操作系统是怎么操
作内存地址感到好奇,也就是我想问:操作系统得到一个虚拟地址后,它是怎么决定如何去
获取该虚拟地址对应的内容的?另外有一个问题,c程序中的FILE*和char*,它们都是虚拟地
址,但FILE*指针指的是硬盘空间,char*指针指的是内存空间,对吗?(看完你回答的第二
句,想问的问题)
③差的操作系统,程序员需要的数据指的是什么?是程序员写的程序需要的数据,还是程序
本身?如果是程序本身的话,运行的时候要加载到内存我理解,但是“有些算法让80%的数据
已经从硬盘载入内存了”这句话我不理解,我不是想问它怎么让80%数据已经载入内存了,而
是想问这80%数据到底是谁的80%数据,如果能帮忙举个例子最好了,非常感谢。(看完你回
答的第三句,想问的问题)
④任意程序占有4G空间,大不了从硬盘加载,那么程序A,malloc(3G),程序B,malloc(2G),应
该是没问题的对吧,哪怕再来个程序C,malloc(4G),……,也是没问题的对吧(硬盘足够大,看完你回答的第四句,想问的问题)
⑤"每个时刻只会有一个线程在内存中"这个话是我说错了,但我的意图是想问这句话跟解释虚拟地址有什么关系,以前查相关资料的时候,遇到过这句话,但是没看懂什么意思。

每一个问题都不是一言两语说的清楚的,如果你能抽个空帮忙理解一下,或者简要的用一句关键的话或词回答,我都非常感觉,如果没时间也没关系,我最终都会弄明白的,只不过是时间问题,你现在这个回答已经对我帮助很大了,thand you, good night 。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-2 22:53:53 | 显示全部楼层
Tzdner_C 发表于 2012-7-2 19:05
想明白,就自己去学windows的保护模式,这其中的关系错综复杂不是一两句能给你解释清楚的。。。就算你拿出5 ...

刀子嘴,豆腐心,谢谢回答。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-3 00:16:53 | 显示全部楼层
Tzdner_C 发表于 2012-7-2 19:05
想明白,就自己去学windows的保护模式,这其中的关系错综复杂不是一两句能给你解释清楚的。。。就算你拿出5 ...

为什么说ds.base说了我也无法理解,不就是基址吗,4G要64位二进制,32根线不够,就用了这个寻址方法,太小看我了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-3 12:31:08 | 显示全部楼层
_nosay丶 发表于 2012-7-3 00:16
为什么说ds.base说了我也无法理解,不就是基址吗,4G要64位二进制,32根线不够,就用了这个寻址方法,太小 ...

;P  原来你真的不懂。。。4G64位2进制   ;P     那你知道ds.base  limit知道吗? attributes知道吗? selsctor知道吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-3 12:36:03 | 显示全部楼层
Tzdner_C 发表于 2012-7-3 12:31
原来你真的不懂。。。4G64位2进制        那你知道ds.base  limit知道吗? attributes知道吗? sel ...

不知道,求解释。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-3 13:29:29 | 显示全部楼层
① long long ago,运行一个可执行文件不是像现在鼠标点点就行了,要程序员自己调到内存

,那程序员是怎么将要运行的程序调到内存的,现在鼠标一双击,操作系统又是怎么知道程
序在硬盘中的位置的?(看完你回答中的第一句话,想问的问题)

其实硬盘它就是个外设,本质上和鼠标键盘什么的区别不大.但内存就合CPU联系比较紧密了.(Long long ago)要将运行的程序调到内存.程序呀首先要访问一个外设"硬盘",从硬盘读取程序,读到内存里面.其实现在在很多嵌入式系统开发的时候,仍然没有操作系统,这个过程还是要由伟大的程序员来操作.
而现在操作系统掌管了整个电脑.所以,当你用鼠标点击屏幕上的图标的时候,操作系统知道你点击的图标表示哪个程序,也知道这个程序在硬盘里的位置(具体的过程你可以深究<操作系统>这门课.其实直观的想也很简单:整个电脑桌面不就是经由操作系统才画上去的吗?那你认为你在上面点击鼠标操作系统不知道吗?).于是操作系统将访问那个叫做"硬盘"的外设,把需要的数据读到内存里面.

OK.我决定一天回答你一个问题,毕竟我还有其它活要干.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-3 15:03:50 | 显示全部楼层
仰望天上的光 发表于 2012-7-3 13:29
其实硬盘它就是个外设,本质上和鼠标键盘什么的区别不大.但内存就合CPU联系比较紧密了.(Long long ago)要将 ...

thank you, 期待明天,后天,大后天 。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-3 18:13:45 | 显示全部楼层
_nosay丶 发表于 2012-7-3 12:36
不知道,求解释。

我也一天告诉你一点点。。。我每天还有活要干。。。告诉你在32位PC机。。也就是80386及以后的CPU,段寄存器都是96位,分为16位的选择字selector 16位的属性 attributes 32位的base 还有32位的limit界限。。。构成。。。。4GB也就是0x100000000  ,地址从0开始记,最高地址也就是0xFFFFFFFF  ;P用计算器算下看多少位;P  不晓得你64位如何算的????  进制转换都是问题,怎么就敢研究这么高深的一些问题???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-3 19:09:30 | 显示全部楼层
的风格很舒服的故事
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-3 20:59:22 | 显示全部楼层
Tzdner_C 发表于 2012-7-3 18:13
我也一天告诉你一点点。。。我每天还有活要干。。。告诉你在32位PC机。。也就是80386及以后的CPU,段寄存 ...

对呀,4G=2^32,我怎么说64位,当时应该是想到8086用16根线寻1G空间用的那个方式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-3 21:02:08 | 显示全部楼层
———— 发表于 2012-7-3 19:09
的风格很舒服的故事

你的回答经过加密了吗?从头到尾读了好几遍没明白什么意思。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-3 22:15:37 | 显示全部楼层
_nosay丶 发表于 2012-7-3 20:59
对呀,4G=2^32,我怎么说64位,当时应该是想到8086用16根线寻1G空间用的那个方式 。

你又错的严重了。。。8086是16根线寻址1M,不是1G大哥。。。;P  你彻底完蛋了。。。。8086太简单了不值得拿出来讨论了。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-3 22:56:54 | 显示全部楼层
Tzdner_C 发表于 2012-7-3 22:15
你又错的严重了。。。8086是16根线寻址1M,不是1G大哥。。。  你彻底完蛋了。。。。8086太简单了不值得 ...

每个进程都占有4G内存,是能寻址4G,不是拥有,就是说可利用的4G空间放那里是固定不变的,每个进程都有能力找到这4G的每个“角落”,但是可以拥有的只有那些还没有被占用的“角落”对吧,那么代表凤姐,小月月请教你,操作系统何必返回一个虚拟地址给程序员,如果分配到0x00000000就返回0x00000000就是了,分配到0xFFFFFFFF就返回0xFFFFFFFF就是了,其实问来问去我还是没有真正的明白操作系统是怎么得到虚拟地址和怎么用它去找真实物理地址的,我暂时不能把找到的资料联系起来,有提到内存分页机制的,线性地址转换的,硬盘分出来的那部分虚拟内存,你说先要学习windows保护模式吗,你理解虚拟地址是怎样的过程?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-4 09:44:39 | 显示全部楼层
本帖最后由 仰望天上的光 于 2012-7-4 09:46 编辑
② 操作系统谋权但没篡位,要对内存进行什么操作时,还是由我们发出指令,但操作者是它
,其实也就是微软那些N人搞出个操作系统往那一扔,淡淡的加上一句“咯,用它你可以可方
便的操作电脑了”,从而让大多数人都停留在了操作系统之上,也让我对操作系统是怎么操
作内存地址感到好奇,也就是我想问:操作系统得到一个虚拟地址后,它是怎么决定如何去
获取该虚拟地址对应的内容的?另外有一个问题,c程序中的FILE*和char*,它们都是虚拟地
址,但FILE*指针指的是硬盘空间,char*指针指的是内存空间,对吗?(看完你回答的第二
句,想问的问题)

现代操作系统的一个特点就是支持多任务,就是说很多个程序可以同时运行,就像你可以一边玩游戏,一边听音乐,一边上QQ。问题是实际内存最多只有4GB,但每个运行的程序都认为它可以独占这4GB的内存。在真实情况下这显然不可能。于是操作系统介于程序和真实内存之间开始发挥它的作用了。比如说,游戏程序使用的4GB空间是由实际内存的0.5GB和在硬盘上的3.5GB组成的。(显然在某个瞬间,某个程序正在使用的内存不可能非常大),当游戏程序要访问的内容位于在硬盘上的3.5GB的时候,操作系统就将原先那0.5GB的内容写入硬盘,再从硬盘读需要的0.5GB新内容 (实际情况可能和这个有些出入,但理念是一样的)。所以,游戏程序认为它可以使用的任意4GB内存实际上仅仅使用了0.5GB内存。

显然其它几个同时运行的程序也都被操作系统施用了类似的手段。

这样做的主要好处就是系统现在可以同时运行多个程序了。

当然,LZ提出了一个尖锐的问题,就是操作系统如何将虚拟地址转换为真实的内存地址。按照我前面的解释,这个问题本身就是由问题的。因为你随便提出的一个虚拟地址,它不一定就刚刚好在内存里,也许需要操作系统将硬盘上的某部分调入内存,然后再访问该内存。至于具体的算法,我相信操作系统的书讲得比我好。但简单想想,这所有的幕后的事情都是操作系统作的,它要以某种合理的方式给出正确的内存地址,不是什么很困难的事情。

c程序中的FILE*和char*变量它们都是指针,一个指向结构体FILE,一个指向基本类型char。它们本身都是存在于内存里的。你以为fopen的返回值真的代表硬盘里的文件吗?不对,它仅仅是记录了该文件的一些相关信息。你想想你是怎么得到文件内容的?难道不是调用fread之类的函数吗?该函数的底层实现会将文件的一些信息告诉操作系统(File*参数就记录了这些 信息),于是操作系统开始访问一个叫做“硬盘”的外设,把数据读到内存里。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-4 09:49:10 | 显示全部楼层
回复累得要死,Tzdner_C 你来当版主吧,多回答问题也能把学到的知识巩固下。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-4 09:51:50 | 显示全部楼层
Tzdner_C 发表于 2012-7-3 22:15
你又错的严重了。。。8086是16根线寻址1M,不是1G大哥。。。  你彻底完蛋了。。。。8086太简单了不值得 ...

8086   20根地址线好不好?不学8086你难道直接就明白其它CPU的结构?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-7-4 10:53:50 | 显示全部楼层
仰望天上的光 发表于 2012-7-4 09:44
现代操作系统的一个特点就是支持多任务,就是说很多个程序可以同时运行,就像你可以一边玩游戏,一边听音 ...

隐约看到了一线光,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-24 04:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表