为什么在64位Windows中运行时2 GB内存限制?

时间:2010-04-29 19:45:02

标签: delphi delphi-2007 win64

我是开发Delphi应用程序的团队的成员。内存需求量很大。 500 MB是正常的,但在某些情况下它会出现内存异常。在这种情况下分配的内存通常介于1000 - 1700 MB之间。

我们当然需要64位编译器,但现在不会发生(如果它发生,我们也必须转换为unicode,但这是另一个故事......)。

我的问题是为什么在64位环境中运行时每个进程有2 GB的内存限制。指针是32位,所以我认为4 GB是正确的限制。 我使用的是Delphi 2007。

修改 因此,如果我使用以下命令在Delphi中设置IMAGE_FILE_LARGE_ADDRESS_AWARE标志:

{$SetPeFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

在Windows Server 2003 x64上运行生成的Exe文件,然后应用程序可以处理4 GB?

  • 我应该在boot.ini中设置/ 3GB开关吗?
  • 我们尝试了这个但是在32位Windows Server 2003上它似乎限制了Windows资源。在日志中使用GDIError的“Out of memory”有更多例外。但是当在64位操作系统中运行时,这可能会消失吗?

4 个答案:

答案 0 :(得分:32)

如果使用/ LARGEADDRESSAWARE标志编译Delphi应用程序,它将能够在64位操作系统上处理完整的4GB。否则,当在WOW32中运行时,操作系统假定应用程序期望与32位操作系统相同的环境,这意味着4GB的地址空间,2GB专用于操作系统,2GB分配给申请。

答案 1 :(得分:14)

Delphi中用于在PE可执行文件中设置LARGEADDRESSAWARE标志的语法是:

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

将它放在.dpr文件中。

答案 2 :(得分:6)

http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx

每个32位进程的用户模式虚拟地址空间:2 GB

答案 3 :(得分:2)

只要您选择接收具有高位设置的32位指针(通过包含LARGE_ADDRESS_AWARE PE标志),就没有2GB的限制。

直接观察

var
   p: Pointer;
   n: Int64;
begin
   p := Pointer($D0000000); //Above the 2GB line; and the 3GB line!

   p := VirtualAlloc(p, 1024, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
   if p = nil then
      RaiseLastWin32Error;

   n := Cardinal(p);
   ShowMessage(IntToHex(n, 16));
end;

enter image description here

结论

在64位Windows上没有2GB限制,只要您发誓可以处理超过$ 7FFFFFFF的指针。

  

注意:任何代码都会发布到公共域中。无需归属。