如何使我的32位Delphi应用程序在64位Windows上(通过Wow64.exe)使用4GB内存?

14
根据这个MSDN页面
WOW64使32位应用程序能够利用64位内核。因此,32位应用程序可以使用更多的内核句柄和窗口句柄。但是,在WOW64下运行时,32位应用程序可能无法像在x86体系结构上本地运行时那样创建许多线程,因为WOW64为每个线程分配了一个额外的64位堆栈(通常为512KB)。此外,一些地址空间保留给WOW64本身和它使用的数据结构。保留的数量取决于处理器;在Intel Itanium上保留的比在x64处理器上保留的更多。
如果应用程序在映像头中设置了IMAGE_FILE_LARGE_ADDRESS_AWARE标志,则每个32位应用程序在WOW64环境中将接收4GB虚拟地址空间。如果未设置IMAGE_FILE_LARGE_ADDRESS_AWARE标志,则每个32位应用程序在WOW64环境中将接收2GB虚拟地址空间。
如何有效地在Delphi 2007应用程序中设置IMAGE_FILE_LARGE_ADDRESS_AWARE标志,以使我的32位应用程序Wow64“感知”并寻址高达完整的4GB内存?
4个回答

19

1
我不确定这会对任何人有所帮助,但是这个指令应该在使用WinApi.Windows之后使用,因为某些Delphi版本需要它才能正常工作。 - kwadratens

14

使用链接器指令$SetPEFlags:

{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

常量IMAGE_FILE_LARGE_ADDRESS_AWARE在Windows.pas中定义。我不记得哪个Delphi版本首次包含它了。

在Delphi 2007中,您可以在“PE(可移植可执行文件)头标志(Delphi)”中找到SetPEFlags的文档。

一些有用的IMAGE_FILE_HEADER标志

  • {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} //$0020

    应用程序可以处理大于2 GB的地址。

  • {$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP} //$0800

    如果映像在网络上,请将其复制到交换文件并从其中运行。

  • {$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP} //$0400

    如果映像位于可移动介质上,请将其复制到交换文件并从其中运行。

一些IMAGE_FILE_HEADER标志:

  • {$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_NX_COMPAT} //$0100

    映像与数据执行预防(DEP)兼容。

  • {$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE} //$0040

    DLL可以在加载时重定位。(也称ASLR-地址空间布局随机化)

  • {$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE} //$8000

    映像已知晓终端服务器。


9
请注意,编译器和运行时库(RTL)中都有一些假设,即将指针解释为带符号的32位整数时,它们永远不会为负数。例如,编译器不允许创建大于2GB大小的数据结构,并且RTL中的某些边界检查假定例如Index + Count < 0意味着加法溢出,其中Index可能是一个字节数组的索引。在内存管理器中可能会出现其他问题。

请进行充分测试并自行承担风险。


如果RTL/VCL存在任何问题,是否有机会修复呢? :) - Alex
为什么指针会被解释为有符号的32位整数?这听起来像是一个有缺陷的设计,Embarcadero 应该修复它,特别是因为你似乎不急于发布 Delphi 的64位版本。 - Jan Goyvaerts
3
我会尽力进行翻译,以下是您需要翻译的内容:@Jan Goyvaerts - 我所描述的检测溢出的方法需要简单、易懂且高效。营销和产品决策是否采用64位等与我在此发出的具体技术警告完全无关。 - Barry Kelly

3

如果您这样做,请确保使用FastMM,因为它支持> 2GB指针。早期的Delphi内存管理器不会像Barry Kelly已经描述的那样工作得很好。


链接:FastMM4 支持 Delphi 4 及以上版本,FastMM5 支持 Delphi XE3 及以上版本。 - AmigoJack

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