64位进程的进程内存限制

20

我目前拥有一款32位的.NET应用程序(在x86 Windows上),需要大量内存。最近它开始抛出System.OutOfMemoryException异常。

因此,我计划将其移植到x64平台上作为64位进程。这样做是否有助于解决内存溢出异常问题?我正在阅读MSDN上的这篇文章 Windows的内存限制

所以我的问题是,如果我编译一个64位的.NET应用程序,它会默认设置IMAGE_FILE_LARGE_ADDRESS_AWARE吗(正如该文章所建议的那样)?也就是说,我能否利用8GB用户模式虚拟地址空间的优势?

5个回答

16

x64进程的最大内存限制为8 TB,但实际限制要少得多,因为它取决于您系统中的物理内存和页面文件大小。有关更多详细信息,请参见此帖子

IMAGE_FILE_LARGE_ADDRESS_AWARE会影响在x64操作系统上运行的x86进程(或具有/3GB指令的x86操作系统)。您的x64应用程序不需要设置大地址感知标志,它将能够使用系统上所有可用的虚拟内存。


15

IMAGE_FILE_LARGE_ADDRESS_AWARE只适用于32位进程。原因是在32位Windows上,地址空间被分为两部分:2 GB内核空间和2 GB用户空间。为了寻址2 GB,需要31位。也就是说,32位应用程序中的指针不需要最后一位来寻址。

某些应用程序可能会将这个额外位用于自定义目的,因此如果Windows内存管理器突然将真正的32位地址交给它们,它们无法处理。通过启用IMAGE_FILE_LARGE_ADDRESS_AWARE标志,应用程序基本上告诉操作系统它可以处理整个32位可寻址空间。

如果在32位Windows上运行一个IMAGE_FILE_LARGE_ADDRESS_AWARE应用程序,则可以访问3 GB。如果在64位Windows上运行相同的32位应用程序,则该进程实际上得到整个4 GB地址空间。

如果在64位Windows上运行64位应用程序,则用户地址空间为8 TB(另外有8 TB保留给内核地址空间)。设置为AnyCPU的.NET应用程序将自动成为x64上的64位应用程序,因此您无需进行任何操作即可寻址额外的内存。

请注意,CLR对任何单个对象施加了2 GB的限制,因此虽然您的应用程序可能使用大量内存,但不能创建2 TB的数组。关于这个问题更多信息可以参考这个问题:在CLR 4.0中单个对象仍然限制为2 GB大小吗?


1
对于32位寻址方案(总共有4GB地址),Windows将整个空间分为两部分,即2GB用于操作系统内核,2GB用于用户进程。对于64位寻址方案,似乎他们没有采取将整个地址空间分成两个相等部分的路线。64位寻址方案总共有16777216TB,但他们将内核和用户进程空间限制在8TB。 - RBT

8

在x64操作系统上,如果您的应用程序是为AnyCPU编译的,则无需进行任何特殊处理。 JIT将在运行时创建x64图像或在32位系统上运行时创建x86图像。


6

实际上,该文章指出您将可以访问8 TB 的虚拟地址空间(是的,这是真的)。


这意味着无需执行任何额外操作即可设置IMAGE_FILE_LARGE_ADDRESS_AWARE。也就是说,64位进程默认情况下具有该开关。我说得对吗? - SysAdmin
如果我们限制自己只使用Windows x64:我认为你的意思是说你可以访问8TB,因为你受到可用物理内存和页面文件存储位置的限制。然而,我们还没有8TB的硬盘。 - ta.speot.is

5

迁移到64位系统确实有助于消除OutOfMemoryExceptions,但您可能希望专注于系统架构和编码机制,以避免这些问题,因为它们在64位机器上出现只是时间问题。
另一个迁移到64位机器的优点是,拥有8TB的虚拟地址空间后,.NET的垃圾回收发生的不频繁。这通过增加程序可用的虚拟空间来提高应用程序性能。


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