我正在创建一个需要使用大量RAM的.NET应用程序(C#)。我最近知道在32位版本的Windows XP上我只能使用2 GB,除非我使用/3Gb
开关,并在可执行标头中设置IMAGE_FILE_LARGE_ADDRESS_AWARE
标志。但是因为我正在开发.NET应用程序,我想我无法直接修改可执行文件,是吗?那么,我该怎么做才能让我的应用程序使用3 GB?
答案 0 :(得分:13)
.NET exe仍然是标准的PE文件;因此,您可以尝试使用editbin /LARGEADDRESSAWARE
来设置标志,但请注意,如果您使用的是ClickOnce(因为它维护文件的加密哈希值),这将无效。
但是,请注意,就单个对象/数组的最大大小而言,您仍将具有相同的.NET限制。对于大量内存,x64是一个更好的主意。
答案 1 :(得分:6)
/ 3GB开关在OS引导加载程序上,而不在您的应用程序上。 (编辑:它也存在于本机C / C ++编译器中,但不存在于C#编译器中)就您的应用而言,它将请求内存,操作系统会将其提供给您的进程。但是,在程序使用虚拟内存之前,您可以再访问1个gig(可能,您并不总是获得3gig,具体取决于您的硬件外围设备)。
正如Marc Gavell向我指出的那样,您可能需要在exe上运行命令“editbin / LARGEADDRESSAWARE my.exe”作为post build选项来启用它。在此处找到了对MS人员的提及:MS Forums
我建议你看看你的程序,看看你是否可以重新架构它以减少内存使用。也许你可以用较小的块来处理数据集,而不是试图将整个事物一次性加载到内存中?
答案 2 :(得分:1)
您还应该增加流程的最大工作集大小:请参阅SetProcessWorkingSetSize API。
答案 3 :(得分:0)
嗯,我不确定这一点,但这就是我的想法:
.NET可执行文件可以通过两种方式编译 - 特定于平台和独立于平台。默认情况下,它们是平台无关的,代码是(如其他答案中所述)在运行程序时JIT使用平台特定代码。
现在,例如,如果您的可执行文件是这些独立于平台的可执行文件之一,并且您在64位操作系统上运行它,它将被JIT转换为64位代码,对吧?因此,它将能够解决超过3GB RAM的问题。
我想说的是 - 我认为在PE标题中写的不重要。可用RAM的实际数量由.NET运行时确定,后者依次查看当前平台并生成最佳的JIT代码。
我认为您不应该担心/ 3GB开关,因为.NET会为您处理它。相信.NET! :)
答案 4 :(得分:0)
您可以尝试通过命名管道使用远程处理,并通过物理上有更多进程来获得更多内存。
如果您正在进行任何形式的互操作(此处为正常的.Net套接字计数),您应该创建一个对象缓存(例如,使用套接字byte []缓冲区),在应用程序启动时分配大量这些对象。
您应该阅读this article。
答案 5 :(得分:0)
我刚刚在 Windows 10(64 位)和 VS2019 上用一个小的 x86 C# 程序对其进行了测试。 默认情况下,我可以在内存耗尽之前分配 1605 个 1Mb 大小的字符串。
通过设置:
"editbin /LARGEADDRESSAWARE my.exe"
我可以在内存耗尽之前分配 3330 个 1Mb 大小的字符串。
在 Windows 10(64 位)上,因此超过 3Gb 空间寻址。
答案 6 :(得分:-1)
据我记忆,/ 3GB开关只能用于Windows Server(2000或2003),但不能用于Windows XP。您需要在boot.ini文件的末尾写入/ 3GB。这样,对于应用程序,OS会启用更多通常分配用于内核进程的内存。但是,/ 3GB并不意味着您可以为您的应用程序使用3GB内存,它只能使用更多内存,但不一定必须是3GB。对于.net应用程序,据我记得,使用/ 3GB开关,你可以使用高达1.8GB的内存。顺便说一下,您可能还想检查/ PAE切换。