最大可达的.NET内存是多少?

16

.NET托管代码能够达到的最大内存量是多少?它是否取决于实际架构(32/64位)?


是的,有这种情况发生。你可以试试,在32位结构中运行时可能会出现约900MB的运行时错误。或者你可以运行一个适当的、甚至不算大的数据集。真是令人沮丧。 - rama-jka toti
如果你需要一个事实,那么最好加载它并在达到内存不足异常时注意一下。问题是你只需要运行几个这样的应用程序(你知道适当大小),然后就会出现问题:CLR 是高效的,理论家们对此感到兴奋。 - rama-jka toti
我可以确认 900 MB 的限制,而且这实际上是一个限制。在过去的六年中,在三个不同的 WinForms 应用程序中,我已经反复看到了它。在最初的几年里,大约是 700 MB,而我见过的最大值大约是 1050 MB。 - Peter Mortensen
9个回答

13

.NET代码没有确定的硬性数字。

如果您在32位Windows上运行,则您的进程可以寻址多达2 GB的空间,在Windows Server 2003上使用/3GB开关则可以寻址3 GB。

如果您在64位框架上运行64位进程,则进程可以寻址高达8 TB的地址空间,如果有那么多RAM可用。

然而,这并不是整个故事,因为CLR每个进程都需要一些开销。同时,.NET会尝试以块的方式分配新的内存;如果地址空间被分段,那可能意味着即使有一些内存可用,也无法分配更多内存。


1
如果有那么多的RAM,它可以寻址整个64位地址空间。这肯定是不正确的,需要进行编辑。 - Jeff Atwood
1
64位Windows下的32位进程可以访问4GB的用户空间(使用大地址标识...与在/3GB开关下访问3GB的标准相同)。 - Richard
@driis,在一台64位机器上,限制是8TB,而不是整个64位地址空间。 - JaredPar
1
你们关于x64上8TB限制的说法都是正确的,我编辑了答案来修正这个问题。(我写答案时可能有点太快了 :-) - driis
3
你可以处理比你的RAM大小更大的内存,因为分配的虚拟内存可以不在RAM中,它可以在页面文件中。 - svick
显示剩余2条评论

7
在C# 2.0和3.0中,托管代码中单个对象的大小也有2G的限制。

7
您的.NET进程可以访问的内存量取决于它是否在32/64位机器上运行,以及它是否作为CPU不可知或CPU特定进程运行。默认情况下,.NET进程是CPU不可知的,因此它将使用与Windows版本相对应的进程类型运行。在64位系统中,它将成为64位进程,在32位系统中,它将成为32位进程。但是,您可以强制.NET进程针对特定的CPU运行,并使其在64位机器上以32位进程运行。如果不包括大地址感知设置,则以下是各种可用空间的详细信息: - 32位进程可以访问2GB - 64位进程可以访问8TB
这里有一个链接,其中包含基于Windows提供的各种选项的可寻址空间的完整细分。

http://msdn.microsoft.com/en-us/library/aa366778.aspx


5
我最近一直在进行关于.NET 32位进程内存限制的详细分析。我们都被灌输了一个观念,即我们可以在.NET应用程序中分配高达2.4GB(2^31)的内存,但不幸的是这是不正确的:( 应用程序进程有那么多可用空间,并且操作系统为我们管理得非常好,然而,.NET本身似乎有自己的开销,典型的现实世界应用程序会占用大约600-800MB的内存限制。这意味着,一旦您分配了一个占用约1.4GB的整数数组,您就应该预计会看到OutOfMemoryException()。

显然,在64位上,这个限制发生得晚得多(让我们在5年后再聊:)),但由于字长增加,内存中所有东西的总体大小也会增长(我发现它大约是1.7到2倍)。

我确定的是,操作系统中的虚拟内存概念绝对不能为一个进程提供几乎无限的分配空间。它只存在于此,以便所有(许多)正在运行的应用程序都可以寻址完整的2.4GB。

希望这些见解能在某种程度上有所帮助。

我最初在这里回答了相关问题(我仍然是新手,所以不确定我应该如何处理这些链接):

单个.NET进程有内存限制吗?


你为什么想要多次发布相同的答案? - John Saunders
抱歉,我是新手。您如何在此网站上链接相关的问题和答案? - Luke Machowski

5
对于64位Windows,虚拟内存大小为16TB,平均分配给用户和内核模式,因此用户进程可以寻址8TB(8192GB)。这比64位可寻址的整个16EB空间少,但仍远远超过32位的常规使用。

3
.NET运行时可以在其主机中分配所有可用于用户模式程序的空闲内存。请注意,这并不意味着所有内存都将用于您的程序,因为一些(相对较小的)部分将用于内部CLR数据结构。在32位系统中,假设设置了4GB或更多的安装(即使启用了PAE),您应该能够最多分配大约2GB到您的应用程序。在64位系统上,您应该能够获得1TB。有关Windows内存限制的更多信息,请查看this page。请注意,每个提到的数字都必须除以2,因为Windows将地址空间的高半部分保留供运行在内核模式(环0)下的代码使用。此外,请注意,每当32位系统的限制超过4GB时,就会隐含使用PAE,因此除非操作系统支持4gt,否则您仍然无法真正超过2GB限制,在这种情况下,您可以达到3GB。

2

是的,在32位环境下,您的地址空间受限于4GB,但Windows占用了一半左右。在64位架构中,它要大得多。我相信它是4G * 4G。

而在紧凑框架上,通常是几百MB的数量级。


2
说4G * 4G会让人们误以为是16G。实际上,4G是2^32字节,接近40亿。而64位限制是2^64 = (2^32)(2^32),即(40亿)(40亿),比16G要大得多。 - Karl

0

0

我认为其他答案都相当幼稚,在现实世界中,当内存消耗达到2GB后,您的应用程序将表现得非常糟糕。根据我的经验,GUI在大量内存消耗后通常会变得非常笨重,难以使用。

这是我的经验,显然,造成这种情况的实际原因可能是对象增长过大,因此对这些对象的所有操作都需要太多时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接