地址空间和虚拟内存(转载)http://topic.csdn.net/u/20090619/10/4c62a13b536b4b0aaf092271c6a104e1.html


我对于虚拟地址空间和虚拟内存的理解:32位的CPU中,一个进程都有个4G的虚拟地址空间;虚拟内存是存在于硬盘上的页交换文件。
前段时间听了一个报告,报告人竟然一再强调说MMU管理的是虚拟内存,个人认为MMU管理的应该是进程的虚拟地址空间吧?
回来查了下《WINODWS核心编程》,发现第五版的中文版本中对这两个概念说的也不清楚,如P362页:磁盘上的文件一般被称为页交换文件,其中包含虚拟内存。难道页交换文件不是等价于虚拟内存吗?

欢迎大家讨论,最后能得出个一致的结论。
 
 








回复次数:38
 





#1楼 得分:0回复于:2009-06-19 11:10:30


就没哥哥给我回答个,是不是太EASY,呵呵
 

 



  • microyzy用户头像
  • microyzy
  • (分也许不少,但别误会俺是高手)

  • 等 级:

#2楼 得分:4回复于:2009-06-19 11:42:36


硬盘上的文件是虚拟内存交换到磁盘的结果,虚拟内存就是你的程序能访问到的那些内存,这是相对于真正的内存物理地址而言,这是我的理解。我觉得,windows核心已经解释得足够清晰了,如果认为模糊,那么多读几次,另外补下基础知识,其实,有几个人完全清楚捏-_-
 

 



  • tumen用户头像
  • tumen
  • (tumen)

  • 等 级:

#3楼 得分:4回复于:2009-06-19 12:30:18


第一个问题:
 
虚拟内存是一个4G的地址空间,是一个空间,有部分对应实在的代码和数据,还有很多是空的地址,不对应实际的代码和数据。
第一个疑点:
 
MMU管理的确实是虚拟内存,它是CPU的一个物理部件。
第二个问题:
 
虚拟内存对应实在的代码和数据存在两个地方,一个是按页存入物理内存(以下简称内存),另一个是按页存入硬盘。在硬盘上的部分是以文件形式存在,目的是为了换入换出内存,所以叫页交换文件。
 
说明白点:页交换文件不是虚拟内存(白马非马),是其中的一种存在形式,另一种形式是内存(黑马也是马)。
问题扩充:
 
举例,可执行文件运行时要先装载,但并没有把所有代码和数据从硬盘复制到内存(内存和硬盘中各有部分,并且以页形式存在,一般页有4KB大小),当程序执行到某个代码或数据时,如果内存中没有,那么CPU就产生一个异常(因为CPU只能直接存取在内存中的代码和数据,不能直接访问硬盘中的),然后通过MMU控制把对应的代码或数据的页从硬盘调入内存,再回到产生异常的指令,重新执行(当然代码或数据已经在内存,这次不产生异常了)。
问题溯源:
 
那为什么不全部调入内存?
  因为要在我的32M的物理内存的586电脑中执行大于32M的程序(比如WIN2000)。
 
还有一个好处,可以把物理内存中长时间没用到的数据和代码页移出到硬盘,腾出内存空间我再开始运行另一个新的程序。
 
还有一个好处,....虚拟内存的用处很多。
 

 




#4楼 得分:0回复于:2009-06-19 12:35:45


虚拟内存就是用页面文件来充当内存使用.
某种意义上是一致的,但不是绝对相等的
 

 



  • tumen用户头像
  • tumen
  • (tumen)

  • 等 级:

#5楼 得分:0回复于:2009-06-19 12:37:36


“还有一个好处,可以把物理内存中长时间没用到的数据和代码页出到硬盘中的页交换文件,腾出内存空间我再开始运行另一个新的程序。”

这样改一下更好理解。
 

 



  • wocow3用户头像
  • wocow3
  • (wocow3)

  • 等 级:

#6楼 得分:4回复于:2009-06-19 12:50:09


虚拟内存是一个Windows内存管理的概括
非要说是由什么组成的:物理内存、页文件和映射文件都是虚拟内存机制的一部分

说虚拟内存就是页文件并不正确,映射文件的部分后援存储器都是直接对应磁盘文件的,而不是页文件
 

 




#7楼 得分:0回复于:2009-06-19 13:41:53


非常感谢以上各位的回答,谈谈自己的看法。
microyzy:虚拟内存就是你的程序能访问到的那些内存,我认为这句话是不确切的。程序的进程地址空间的用户区所有映射的内存,我的程序应该都能访问,包括实际的物理内存。
tumen:虚拟内存是一个4GB的地址空间,-----。我认为虚拟内存理论上是最大值是4GB的地址空间(32位寻址),但实际上虚拟内存仅仅是进程地址中映射到页交换文件中的那部分。
wocow3:说虚拟内存就是页文件并不正确,映射文件的部分后援存储器都是直接对应磁盘文件的,而不是页文件。文件映射部分绝对不是虚拟内存机制。

综合以上各位的回答,有几个相互混淆的概念:
1、进程地址空间和虚拟内存应该不是同一概念,在tumen的叙述中我觉得存在将两者等价的嫌疑;
2、虚拟内存和实际的物理内存绝对不是一个谁包含于谁的概念。在tumen、wocow3的叙述中都有将物理内存划入到是虚拟内存机制的一部分之嫌疑。我觉得虚拟内存应该是相对于物理内存而言的。

目前我的理解:
每个进程都有个4G的进程虚拟地址空间,虚拟地址空间和实际的物理存储介质(包括物理内存、硬盘等)具有映射关系,而映射到页交换文件的那部分即为虚拟内存。

请大家批评修正。
 

 




#8楼 得分:0回复于:2009-06-19 14:04:12




引用 4 楼 sandyandy 的回复:
虚拟内存就是用页面文件来充当内存使用.

某种意义上是一致的,但不是绝对相等的
某种意义上是一致的?哪种意义上是一致的?
但不是绝对相等的?什么时候体现出区别?
还请sandyandy兄详细指教。
 

 



  • wocow3用户头像
  • wocow3
  • (wocow3)

  • 等 级:

#9楼 得分:0回复于:2009-06-19 14:18:41


代码和数据要放到内存中才能跑
虚拟内存就是一种机制,让有限的物理内存运行更大更多的程序。
当物理内存中不够时,需要将内存的页换出或是丢弃。
那么对于映射文件,直接在内存中清除就可以了,而不是换出到页文件保存。
 

 




#10楼 得分:0回复于:2009-06-19 14:29:29


搅胡了~~
虚拟内存空间就是操作系统让你觉得你能使用的内存空间吧。
 

 




#11楼 得分:0回复于:2009-06-19 14:39:33




引用 9 楼 wocow3 的回复:
代码和数据要放到内存中才能跑

虚拟内存就是一种机制,让有限的物理内存运行更大更多的程序。
当物理内存中不够时,需要将内存的页换出或是丢弃。

那么对于映射文件,直接在内存中清除就可以了,而不是换出到页文件保存。
如果说虚拟内存是一种机制的话,我同意,但是,虚拟内存机制和文件映射的机制明显不是一样的。
虚拟内存机制应该只是内存管理机制中的一种。
虚拟内存机制是在给进程地址空间划拨实际物理存储器时,用的是页交换文件。不知这样wocow3兄是否同意?
 

 



  • wocow3用户头像
  • wocow3
  • (wocow3)

  • 等 级:

#12楼 得分:0回复于:2009-06-19 16:04:14


虚拟内存机制是在给进程地址空间划拨实际物理存储器时,用的是页交换文件。
-------------------
当然不全是,可执行程序的代码段多是直接映射内存的。在划拨实际物理存储器不用页交换文件
 

 




#13楼 得分:0回复于:2009-06-19 16:10:00


每个进程都有独立的虚拟内存
 

 




#14楼 得分:0回复于:2009-06-19 16:45:20




引用 12 楼 wocow3
的回复:

虚拟内存机制是在给进程地址空间划拨实际物理存储器时,用的是页交换文件。
-------------------

当然不全是,可执行程序的代码段多是直接映射内存的。在划拨实际物理存储器不用页交换文件
可执行程序的代码段是用的直接映射,划拨存储器时也是不用页交换文件.但是这种方式就不是
虚拟内存机制,而是文件映射.
 

 



  • tumen用户头像
  • tumen
  • (tumen)

  • 等 级:

#15楼 得分:0回复于:2009-06-19 20:16:34


搞深了。如果不怕不明白,我就往深处说说。

 
虚拟内存世上本不存在,在8086,或者说80186(不要说没听过,后来多用于单片机了)以前,程序对内存的访问,不管是代码地址还是数据地址,都是直来直去,是几号单元就去几号内存单元找,当然,最复杂的也就算
段地址×16+偏移地址了。
  从286开始引入虚拟内存,当然,我们现在很少见到针对286虚拟内存的程序。
 
经过完善,386时虚拟内存全面登场,“虚拟内存”加上“32位数据和地址”两大特性成为划时代的经典CPU,这也是现在很多操作系统文件中残留i386、386、32等字样的历史原因。
 
386的一大突破就是设计了一个功能强大(相对286)可以使用虚拟内存地址寻址的MMU(内存管理单元),把物理内存(简称内存)划分成一页一页来管理,一页内存大小是固定的(一般是4KB并按4KB地址对齐),把每页的首地址按顺序排成一个数组放在内存,称为页表,页表的大小也是固定的,再把页表的首地址排成数组放在内存,称为页目录表,再把页目录表的首地址用一个专用CPU寄存器保存。
 
程序代码通过MMU进行虚拟内存寻址时,先取出专用寄存器中保存的页目录表首地址,再用32位虚拟地址的高20位作为索引来一层一层的查目录表查页表找到物理内存页的首地址,用虚拟地址低12位(对于4kb页)做页内偏移来找到指定单元。

如果非要说的再明白一点,那么:虚拟内存就是程序代码不能直接访问物理内存的一种间接访问物理内存的机制。或者说是把程序中的地址值x和物理内存单元地址值y用y=f(x)的方式架开分隔。

每个进程都有自己的一套独立的页表和页目录(在进程创建时建立),CPU切换进程时,只要把下一个进程的页目录表的首地址写入专用寄存器,就开始寻址该进程的代码和数据了(页目录表的首地址是领导,领导换了,下面的页目录和页表这些小头目也变成了另一套班子了)。

对于一个进程来说,它能见到和使用的一切内存地址都是虚拟内存地址(不管访问最终目标的是在内存中,还是硬盘上),物理内存地址也就只有操作系统偶尔私自在背后把玩把玩,什么时候都不要认为你的程序中的地址是物理内存地址,它会去直接访问物理内存地址。(除非你是在做操作系统)

在物理内存中只有一套操作系统的代码,把所有操作系统代码页的页首地址在每个进程的页表和页目录表中都抄一份,那么每个进程就可以共享同一个操作系统的代码了。

虚拟内存地址通常绝不等于物理内存地址,隔了十万八千里,风牛马不相及。

当然,页表和页目录中有很多不对应物理内存页的空项,这些空项要么是程序没用到那么多的内存,要么该页放在了硬盘上,这些信息在页表项和页目录表项的指定位上有标记指示,当MMU查到这些页表项或页目录表项时,会根据标记确定是出错(因为访问了程序使用范围外的虚拟内存地址)或者调入硬盘中对应的映射页到内在存并登记页表和页目录更改对应项的标记。

同样,即使没有映射到硬盘上一个字节,你的程序全部装载到物理内存,进程使用的还是虚拟内存地址,因为虚拟内存和是否使用硬盘没有必然关系,说的直白一点,即使一台没有硬盘的电脑,它也能使用虚拟内存。

系统并不机械地建立一个从00000000h到0ffffffffh的4GB虚拟内存映射的页表和页目录,只对那些隔三插王的使用了的虚拟地址才建立对应的页表和页目录,否则的话,小小的内存全被一个个进程的页表和页目录填满了。



这些基本原理明白后就可以清醒了。
 

 



  • tumen用户头像
  • tumen
  • (tumen)

  • 等 级:

#16楼 得分:0回复于:2009-06-19 20:22:50


在WindowXP上编程,就是在使用虚拟内存。
 

 




#17楼 得分:0回复于:2009-06-20 09:37:34




引用 16 楼 tumen
的回复:

在WindowXP上编程,就是在使用虚拟内存。
tumen:
 
您好!
感谢你给出的很多原理性的解释,通俗易懂,让我学到了
很多东西.但是,我始终认为你把进程的虚拟地址空间和虚拟
内存的概念搞混淆了,呵呵,也许我太犟,不过纯粹是学术讨论,
还请不吝赐教.
 

 




#18楼 得分:3回复于:2009-06-20 11:12:57


我觉得,虚拟内存与虚拟内存管理技术是不同的概念

虚拟内存是与物理内存对应的一个概念,指的是有假包换的假内存,也就是用硬盘充当(冒充)的内存

至于虚拟内存管理技术,进程空间那是另外一套符号体系:)
 

 




#19楼 得分:0回复于:2009-06-20 12:04:06




引用 18 楼 ok1234567 的回复:
我觉得,虚拟内存与虚拟内存管理技术是不同的概念


虚拟内存是与物理内存对应的一个概念,指的是有假包换的假内存,也就是用硬盘充当(冒充)的内存


至于虚拟内存管理技术,进程空间那是另外一套符号体系:)
感谢OK1234567的回复,我非常赞同你的解释.也就是说,虚拟内存和虚拟内存管理技术、进程地址
空间是不同的概念。并且虚拟内存就是硬盘充当的那部分内存,即是页交换文件的一部分。希望大家能得
出个统一的认识,求同存异。
 

 




#20楼 得分:0回复于:2009-06-20 13:49:03


我理解:进程地址是一个程序的运行空间,程序的运行需要在内存中进行,虚拟内存技术实现了进程地址到内存地址的映射。
 

 




#21楼 得分:3回复于:2009-06-20 21:04:57


虚拟地址空间包括已分配和未分配的空间,已分配的就是虚拟内存,虚拟内存的储存单元可能是物理内存,也可能是磁盘文件。
 

 



  • zufei用户头像
  • zufei
  • (Vc猪仔)

  • 等 级:

#22楼 得分:2回复于:2009-06-21 01:24:59


记得以前的286,386 CPU内存是分开的,一个是代码段,另外一个数据段,后来到MMX
就改了,好像说用线性内存管理,
我觉得tumen兄,讲的是CPU对内存寻址技术(虚拟内存管理技术)好像是单片机8031+RAM
而所谓"虚拟内存"是在Win系统下建立,有相应多的硬件I/O支持,有不经CPU的大流量数据块传输(DMA),有硬盘..等等!

随便说说而已,错了多多包涵!

 

 



  • tumen用户头像
  • tumen
  • (tumen)

  • 等 级:

#23楼 得分:0回复于:2009-06-21 14:23:29


我在楼主的帖子上耗费的时间已有5个小时,(不要认为仅仅是打几十个字的时间,我要针对问题去长时间思考和组织语言,目的是用简单的语言说明白,我从不喜欢从GOOGLE的搜索结果中粘贴,我认为我知道的我一定能说明白),但我认为这点时间还是值得。很大的原因在于我不想让曾经困惑我很久的问题让后来者再踏上同一条曲折的弯路。


引用 7 楼 jcsnwpu 的回复:
非常感谢以上各位的回答,谈谈自己的看法。

microyzy:虚拟内存就是你的程序能访问到的那些内存,我认为这句话是不确切的。程序的进程地址空间的用户区所有映射的内存,我的程序应该都能访问,包括实际的物理内存。

tumen:虚拟内存是一个4GB的地址空间,-----。我认为虚拟内存理论上是最大值是4GB的地址空间(32位寻址),但实际上虚拟内存仅仅是进程地址中映射到页交换文件中的那部分。

wocow3:说虚拟内存就是页文件并不正确,映射文件的部分后援存储器都是直接对应磁盘文件的,而不是页文件。文件映射部分绝对不是虚拟内存机制。


综合以上各位的回答,有几个相互混淆的概念:
1、进程地址空间和虚拟内存应该不是同一概念,在tumen的叙述中我觉得存在将两者等价的嫌疑;

2、虚拟内存和实际的物理内存绝对不是一个谁包含于谁的概念。在tumen、wocow3的叙述中都有将物理内存划入到是虚拟内存机制的一部分之嫌疑。我觉得虚拟内存应该是相对于物理内存而言的。


目前我的理解:

每个进程都有个4G的进程虚拟地址空间,虚拟地址空间和实际的物理存储介质(包括物理内存、硬盘等)具有映射关系,而映射到页交换文件的那部分即为虚拟内存。


请大家批评修正。

 
对于以上问题和疑惑我认为我已经说明白了,但又为什么不能让人明白,我只好模拟通常学东西的方法,上GOOGLE搜了一下“虚拟内存”,我明白了,我也想起了我以前走的弯路。
 
又是微软,又是WINDOWS,还是微软,还是WINDOWS。
  再说两段,能明白就明白吧。
   
 
1.如果是网管,或者经常修机装系统,能把虚拟内存理解成你设置在硬盘的C盘或D盘或E盘等逻辑盘上一个多达几百MB或几个GB的交换文件,没错,按照微软或者WINDOWS的定义没错,你是合格的,胜任自己的工作。
 
2.如果是编程,特别是中低层相关的系统编程(相对于网页、PHOTOSHOP\3DMAX等),按MS的定义你必将走上和我曾经一样的充满困惑和疑虑的弯路。

 
建议两条路可走:A.抱紧MS的教条,继续疑惑别人的一些观点并一直疑惑下去,成为程序生涯中一个不愿面对的死胡同。B.让MS的教条去死吧,去接受一个真正的、开放意义上的虚拟内存,让自己对电脑软硬件的认识有一个更高视野。低眉信首,疑云随风散。

 
也许我的效率低了,近两个小时,但我还是希望都能明白。
 

 




#24楼 得分:0回复于:2009-06-21 22:55:38


真是无语了,刨根问底是好的,但是不能像孔乙己那样追究茴香豆茴字的写法,那就变成了掉书袋了,毫无意义。
 

 



  • zufei用户头像
  • zufei
  • (Vc猪仔)

  • 等 级:

#25楼 得分:0回复于:2009-06-22 00:35:48


其实“虚拟内存”是宏观概念!就好像两父子,父亲(CPU有虚拟的技术),到儿子(系统)继承了该技术,再发扬光大应用到硬盘上!只不过一些人讲他父亲的属性,一些讲儿子的属性,一些讲他家族的属性!
大家都有道理!!
 

 




#26楼 得分:0回复于:2009-06-22 08:38:41




引用 24 楼 codewarrior
的回复:

真是无语了,刨根问底是好的,但是不能像孔乙己那样追究茴香豆茴字的写法,那就变成了掉书袋了,毫无意义。


感谢您的回复.其实虚拟内存对WINDOWS编程人员来是说,是相当重要的一个概念.也许有很多人像我这样
地在困惑,也许是我的领悟能力太差,但绝不是孔乙己的茴香豆,谢谢.
 

 




#27楼 得分:0回复于:2009-06-22 08:59:12


感谢大家,感谢microyzy,tumen,wocow3,ok1234567,cnzdgs,zufei.
讨论是必要的,争议也是将认识和技术升华的一种的动力.或许最终没有得出一个
统一的结论,但是我还是从这个帖子中受益良多.
最后尤其要感谢tuemn,在这个帖子上花费了很多宝贵的时间,甚至让我一度不能赞成
他的观念,但脑子里却认为他应该是对的,自己尽量朝他的方向去想.但遗憾的是,他最终
未能说服我,也许他的观点是对的.最后,也想给tumen一点建议:你说的很多,也很详细,
从原理上讲也是对的,但更多的是缺少回答问题的针对性,比如我一再和你强调的进程地址
空间和你说的虚拟内存到底是什么区别等,你从未正面回答这些问题.
最后,谢谢大家.祝大家工作顺利,月月加薪!
原文地址:https://www.cnblogs.com/dirichlet/p/1987182.html