微软的操作系统中让 32 位支持大于 4GB 的内存。

先给一个参考文献:The RAM reported by the System Properties dialog box and the System Information tool is less than you expect in Windows Vista or in Windows XP Service Pack 2 or later version

先说结论:

1、PAE允许操作系统在32位模式下使用大于4G的物理内存。

2、不管是否使用PAE,对于单个进程而言,32位系统下可见的地址空间最大只有4G。

3、PAE的优势是可以让不同的进程(在不同的地址空间里)累计使用大于4G的内存,因此而达到使用超过4G内存的目的。

4、WindowsXP系列虽然支持PAE,但实际在使用中最大内存限制在了4G,是人为限制的,原因后面给分析(楼上给出的各种理由都不成立,这里是有技术原因的)。

5、Linux则在开启PAE的模式下能支持在32位系统中使用超过4G的内存。

然后给原因,其实就是我最初给的链接里的内容:

This issue occurs because of a design change in Windows XP SP2 that is also included in Windows Vista. The changes were made to PAE mode behavior to improve driver compatibility.

To reduce driver compatibility issues, Windows Vista and Windows XP Service Pack 2 or a later version include hardware abstraction layer (HAL) changes that mimic the 32-bit HAL DMA behavior. The modified HAL grants unlimited map registers when the computer is running in PAE mode. Additionally, the kernel memory manager ignores any physical address that is more than 4 GB. Any system RAM that is more than the 4 GB barrier would be made unaddressable by Windows and be unusable in the system. By limiting the address space to 4 GB, devices with 32-bit DMA bus master capability will not see a transaction with an address that is more than the 4 GB barrier. Because these changes remove the need to double-buffer the transactions, they avoid a class of bugs in some drivers that is related to the correct implementation of double buffering support.

英文比较长我大概解释一下(以下仅限x86-32/64bit平台,不考虑其它arch):

首先要先科普一下DMA:DMA的意思可以大概理解为:让硬件(比如显卡、声卡、USB、磁盘控制器等)直接操作物理内存,等操作完成以后返回一个中断给操作系统,告诉操作系统说我干完了。

DMA的好处就是:假如我想要往磁盘上写数据,数据已经在内存里了,那么CPU只需要把内存地址告诉磁盘控制器,剩下就不用管了,磁盘控制器完成写操作以后会告诉CPU说写完了,这个期间不耽误CPU做其它的事情。

DMA跟4G内存有什么关系?当然有关系了,因为不是所有内存都是随便都能做DMA的

如果写过64位操作系统的驱动的话,应该会了解到:有一些外设是无法访问超过4G的内存地址的,有些外设做DMA的时候,能访问的地址都是4G以下的地址(如果我没记错,USB-EHCI控制器好像就是这样的)。

因此在64位操作系统里,所有DMA操作都是先专门申请一块专门的DMA内存(4G以下),然后再进行操作。而32位系统里,则一般没有这个限制。

好了,问题就来了:

微软的XP是十几年前的操作系统,在当时的硬件环境里,所有内存都是可以做DMA的。所以在XP的内核API里,没有考虑过内存不能DMA的情况,所以,XP里的各种驱动、软件在写代码的时候,也都没有考虑过内存能不能DMA,只要拿来用就是了。

而十几年间,硬件发生了翻天覆地的变化,而XP由于其强大的兼容性,这方面的API一直都没改进。况且,想改进也不行,因为必须二进制兼容旧代码,并且由于这个兼容性的问题从XP一直延续到了Vista,所以包括Win7在内的各种版本,都必须保持这个兼容性。

二进制兼容这个巨大的包袱使得MS如果真使用了大于4G的内存,那么很有可能出现蓝屏之类的异常情况,因为微软也不知道用户的驱动代码是怎么写的,会不会直接使用内存进行DMA。

所以,微软强行把内存限制在4G以下是为了保持可恨的兼容性。

如果放弃了兼容性可不可以?当然可以了,但那就不是XP而是另一个版本的Windows了。

为什么Server版一直都支持超过4G的内存?因为Server版的驱动跟普通版的不兼容。

所以楼上的所有解释都是不对的,不是市场定位或者照顾用户情绪或者不想让用户这么做,而是因为兼容性无法保证DMA正确执行(微软也解释的很清楚了,但是国内用户似乎没人注意)。

有人提了Ready For 4G,这东西会导致某些程序异常,原因就是这些程序在运行中尝试直接使用物理地址(很多软件就是这么流氓),而代码中获得的物理地址都是32bit的,在某些情况下代码中获得的地址不是实际的物理地址,而导致程序崩溃,说实话,没蓝屏已经很不错了。

如果要让Windows支持超过4G内存,那么几乎所有驱动都要重写一遍,这里还包括操作系统中运行的大量第三方未签名的驱动,这么大的负担显然是谁也承担不了的,因此在32位系统上无法使用4G内存。所以,不是不想,是不能

评论里有人提出,如果专门识别一下驱动,对于非认证的驱动强制限制在4G以下,认证过的驱动允许使用高于4G的地址,这样是否可以?

答案是可以的。问题是这么做代价很大,内核中各个API都要多一条甚至几条检查路径来判断驱动的情况,甚至还要小心驱动代码直接用non-paged内存搞DMA,这么做效率就是一个问题,而且微软是无法拿到所有驱动的源码的,比如显卡厂商一般就只发布binary的驱动,所以,微软无法知道这个驱动里究竟搞了什么小动作。所以不得不把这条路堵死。

******************************************************************************************************************************************

这个问题是这样子的,32位的大限就是4G,这个是一个无法改变的事实,通过什么技术手段都无法改变。每一个32位进程都独享4G的虚拟地址空间,其中低2G是给用户的,高2G是给系统预留的。也就是每一个32位进程中,实际能够使用的内存不到2G。

但是应用程序对于内存的需求总是无止境的,恨不得所有东西都存在内存里面,完全没有磁盘IO。微软对于32位系统有两种使用更大内存的方法。一种是4GT,就是为了让应用程序能够使用更多的内存,压榨一下操作系统保留的地址空间,也就是低3G留给用户,高1G给系统保留,也就是能够利用的内存空间仅仅多了1G而已。但是这种情况,操作系统支持的总物理内存大小没有改变。

另外一种是上面有人提到的PAE,PAE这种支持大内存的方法,也并不能真正解决对于大内存的需求。首先PAE需要硬件支持,也就是CPU具有支持PAE的相关指令。其次,也是最重要的,PAE不能改变每一个进程的虚拟地址空间4G的上限,而是使得操作系统能够分配的物理内存更多一些而已。也就是说,虽然操作系统支持的物理内存总量可以达到32G,但是每一个进程能够使用的最大内存空间也还是2G,开启4GT之后能够达到3G,然后就上不去了。这种利用大内存的方法对于普通用户并不是非常有意义。毕竟服务器上还可以这样,6G内存中,2G给数据库(进程),2G给缓存(进程),2G留给操作系统的其他服务,通过多个进程瓜分大内存。普通家用系统,玩游戏是单独的游戏进程需要大量的内存,而这种情况即使使用PAE也是解决不了的。

所以,如果我们对于内存的需求,是单个进程需要使用大量的内存,那么32位根本不能满足我们的需求,什么样的技术手段都不能够改善。只有升级到64位系统才能够解决这个问题。如果要想在32位系统上充分利用大内存,只能够使用多进程,但是对于大部分需要使用大内存的应用,这种方式也很不靠谱,不同进程之间通信的效率并不高,开发起来还很麻烦,也就是像Chrome这样多进程的程序才能够利用了。

如果微软在非服务器版本中启用PAE支持4G以上的内存,按照现在舆论的风气,一定会被骂出翔。

为什么明明我配了16G的内存也还是玩不了这个内存需求只有4G的游戏啊!!微软你这个大垃圾!!!

像这样的抱怨一定到处都是,微软费力不讨好,何必呢?

Memory Limits for Windows Releases (Windows)

references:

http://www.zhihu.com/question/22594254

时间: 2024-11-03 20:45:54

微软的操作系统中让 32 位支持大于 4GB 的内存。的相关文章

ubuntu 64位android项目报错的解决方案,打开64位 Ubuntu 的32位支持功能

ubuntu的64位下的android环境,说实话,还真得费点精力了,解决一个问题,又出来一个新问题. 小编昨天刚好不容易将android的环境搭建好了,这不,刚建了个项目,直接就报错,下面是罗列出的几条: 1. libstdc++.so.6:cannot open shared object file:no such file or directory 2. Description Resource Path Location Type Error executing aapt: Cannot

怎样打开64位 Ubuntu 的32位支持功能?

大多数使用基于 Ubuntu/Debian 的发行版的人都更倾向于选择64位的系统,对吧?这是因为64位的系统能够充分发挥你的硬件的全部性能, 它使你能够在更紧张的内存资源下使用更复杂的软件,而且是真的快速使用,不必每次做一件小事都要等上许久.现在,32位仅有一个优点,那就是没有太多兼容 性上的问题.每次JAVA更新都很让人很困惑,因为大多数用户都不能获得需要的库文件.在过去,很多别的软件和驱动也没有64位版. 因此, 如果现在你有一个64位架构的系统,而且你可以使用之前的支持:包括驱动.64位

ubuntu 64 位 开发 android 需要安装的 32 位支持库

ubuntu 13.04 及以前可以直接安装 32 位支持库. 以后的版本就只能一条命令一条命令慢慢查了,以下是我发现的需要安装的库. sudo apt-get install lib32z1 lib32stdc++6

64位win2008下IIS未开启32位支持导致DLL无法加载问题

部署一个WEB项目,在本机.本地服务器都没有问题,但部署到远程服务器以后,提示有个DLL无法加载: Server Error in '/' Application. Could not load file or assembly 'Common.Component.Repository' or one of its dependencies. An attempt was made to load a program with an incorrect format. 首先肯定的是,系统声称无法

sql2005性能优化(在32位系统上突破2G内存使用量的方法) .

转载自http://blog.csdn.net/soldierluo/article/details/6589743 服务器磁盘为(SAS)IBM组成RAID0+1,SQL2K5只识别4G内存,实际只占用2G内存.而使用 AWE的话,应用程序可以直接将操作系统允许的最大物理内存量保留为未分页的内存.使用 AWE 使 SQL Server 可以缓存详细信息,而不用从磁盘上的系统页面文件中读取详细信息.通过更快的数据访问提高了性能并减少了访问磁盘的频率.故决定打开SQL2K5的AWE参数,将6G的内

百杂讲堂之为什么32位系统只能操作4g内存

百杂讲堂之为什么32位系统只能操作4g内存 计算机内存中很多的单元,每一个单元就是一个字节,一个字节有8位.每一个单元有两种状态:0和1. 所以 两个单元就有4个组合: 3个单元就有8个组合: 依次类推--: n个地址就有2的n次方组合. 32位计算机,就有32个的单元,就能控制2^32个单元,即2^32个字节,也就是2^32B,等于4GB,所以32位系统的计算机只能控制4gb的内存. 很多人也就想到了,现在有64位的系统,那么也就有2^64个单元,约等于17,179,869,184GB,oh

C# 32位程序,申请大内存,附dome(wpf),亲测可用

原文:C# 32位程序,申请大内存,附dome(wpf),亲测可用 1.我是vs2017,在选装vs的时候,需要安装c++模块,因为申请大内存的必要exe存放在vc的某个目录(下面会给出详细的地址)下的 2.安装完成在vs的安装目录可找到这个文件,我是社区版本的,如果是其他版本也差不多,给大家参照 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\

C#判断系统是64位还是32位 支持.net4.0以前的版本

C#判断系统是64位还是32位的时候引用了一串代码,这个代码是从园子里面其他博文中转载过来的,引入自己的项目中发现无法使用,在引用了相应的命名空间之后还是提示: "未能找到类型或命名空间名称"ConnectionOptions"(是否缺少 using 指令或程序集引用?)": 除了使用 using System.Management; 还需要在解决方案的"引用"中引用才能够起作用,   private string Distinguish64or

对cortex –M0芯片LPC11C14XX中的32位定时器使用的一点认识

作者:杨老师,华清远见嵌入式学院讲师. 在LPC11CXX系列的芯片中有2个32位的定时器,可以用来定时或者计数使用.具有1路32位的捕获通 道,当输入信号发生跳变时可以捕获定时器当前的值,也可以产生中断.具有4路外部匹配寄存器和4路外部输出寄存器.而且每个寄存器可以最大允许3个匹配输 出用来作为单边沿PWM输出. 一.定时器初始化时需要配置的寄存器. IOCONFIG:通过配置对应的引脚寄存器来设置和定时器相关的引脚. SYSAHBCLKCTRL:该寄存器用来开启选择的定时器的时钟. TMR3