2 GB真的是我的最大值?

进程地址空间告诉我,我的.NET应用程序最多只能在Windows XP上使用2 GB。 真的吗?

但是如果我有一个20TB的硬盘呢。 它会不能使用一些驱动器空间?

说这与RAM有关的答案是非常错误的。 正确理解磁盘空间,RAM和地址空间之间的关系非常重要。

这是如何真正的工作。

32位Windows上的每个进程都有一个4 GB的地址空间

在这4 GB的地址空间中,2 GB是为操作系统的使用而保留的,另外2 GB是可用于进程中的用户代码,因为它认为合适。

现在让我非常清楚这一点: 地址空间不是内存 。 一个进程可以拥有尽可能多的内存 。 我会再说一遍: 一个进程可以有超过4 GB的内存分配 。 限制是只有2 GB的内存可以随时映射到用户模式的地址空间

我没有提到RAM,因为RAM与地址空间的问题无关 。 操作系统是否将进程的内存存储在RAM或磁盘上或其他方面并不重要。 RAM只是一个性能优化,可以让操作系统将内存存储在一个快速的芯片中,而不是一个慢速的磁盘。

你的进程告诉操作系统有多less内存,以及将内存映射到2 GB地址空间的位置。 如果进程需要超过2 GB的内存,则将无法将其全部映射到地址空间; 这样一个过程需要被巧妙地编写来告诉操作系统映射哪些页面的内存和从地址空间去映射,还是使用较less的内存。 如果没有,那么它会失败,并出现内存不足的exception。

也许类比会有所帮助。 你的build筑有一个有一百个空间的停车场。 这是RAM。 你在街上有一个停车场,里面有一万个车位。 这是磁盘。 你和大楼里的每个人都有一个钥匙环,上面有十个钥匙的空间。 这是每个进程的地址空间。 你只有十个键的空间是否意味着你只能拥有十辆车? 没有! 你可以拥有任意数量的汽车,但是如果你想要访问那些汽车中的十一个,你将不得不从钥匙圈上取下一个钥匙,把钥匙存放在别的地方,然后把钥匙放在钥匙圈上。 这是映射内存进出地址空间

如果大楼里的每个人都试图将十辆汽车停放在RAM中呢? 如果停车场满了,那么他们就不得不把一些车换到街上的停车场。 这是否阻止他们的钥匙圈上有钥匙? 不,显然不是。 当他们想驾驶停放在磁盘上的汽车时,它会变得很慢。

如果有一个代客服务,弄清楚哪些人更可能使用汽车,并把那些不太常用的汽车搬到街上的停车场呢? 这是内存pipe理器将不太新近使用的内存页面放到交换文件中。

你指出你有一个大磁盘。 假设您在该磁盘上有一个10 GB的文件。 你当然可以在你的.NET程序中使用这个文件的内容,但是你不能一次把它全部加载到连续的地址空间中。 你必须分块阅读。 如果你很聪明,你可以一次性将其映射到进程内存中 – 你有足够的内存 – 但是你不能将10GB的内存映射到2GB的地址空间

总的来说,不要试图获得那么多的记忆, 每次只读几百KB。

人们将地址空间与物理内存混淆是非常普遍的,但几十年来它们并不是一回事。 有关更多详细信息,请参阅关于此主题的文章, “内存不足”不涉及物理内存

Eric Lipperts的答案是100%正确的,你应该先阅读,但我有几件事要补充:

  • 您可以使用所谓的/ 3G开关将2 GB用户模式地址空间限制增加到3 GB – 这是每台机器设置,可将操作系统使用的地址空间减less到1 GB(从2 GB),释放额外的1 GB用于用户模式地址空间。
  • 如果您正在64位操作系统下运行32位进程,那么最大用户模式地址空间限制会增加到4 GB(即使您的应用程序编译为32位进程) – 这可能会有用(例如)由于某些引用仍然只是32位,所以只能定位到x86体系结构。

请注意,上述两个解决scheme都要求设置IMAGE_FILE_LARGE_ADDRESS_AWARE标志。 请参阅如何创build(32位).NET应用程序以使用3 GB RAM? 有关如何可以为.NET应用程序执行此操作的一些build议。