如何使我的 32 位 Delphi 应用程序能够在 64 位 Windows 上使用 4GB 内存(通过 Wow64.exe)?
根据此 MSDN 页面:
WOW64 使 32 位应用程序能够 利用 64 位内核。 因此,32位应用程序可以使用 大量的内核句柄和 窗户把手。不过,32 位 应用程序可能无法创建 WOW64 下的线程数量与它们一样多 在基于 x86 的本机上运行时可以 系统,因为 WOW64 分配了一个 额外的 64 位堆栈(通常为 512 KB) 每个线程。此外,一些 保留的地址空间量 对于WOW64本身和数据 它使用的结构。量 保留取决于处理器; Intel Itanium 上保留了更多 比在 x64 处理器上。
如果应用程序有 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志 在图像头中设置,每个32位 应用程序接收 4 GB 虚拟空间 WOW64 中的地址空间 环境。如果 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志是 未设置,每个 32 位应用程序 接收 2 GB 虚拟地址空间 在WOW64环境中。
如何在 Delphi 2007 应用程序中有效地设置 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志,以便使我的 32 位应用程序 Wow64感知 并寻址到完整的 4GB 内存?
According to this MSDN page:
WOW64 enables 32-bit applications to
take advantage of the 64-bit kernel.
Therefore, 32-bit applications can use
a larger number of kernel handles and
window handles. However, 32-bit
applications may not be able to create
as many threads under WOW64 as they
can when running natively on x86-based
systems because WOW64 allocates an
additional 64-bit stack (usually 512
KB) for each thread. In addition, some
amount of address space is reserved
for WOW64 itself and the data
structures it uses. The amount
reserved depends on the processor;
more is reserved on the Intel Itanium
than on the x64 processor.If the application has the
IMAGE_FILE_LARGE_ADDRESS_AWARE flag
set in the image header, each 32-bit
application receives 4 GB of virtual
address space in the WOW64
environment. If the
IMAGE_FILE_LARGE_ADDRESS_AWARE flag is
not set, each 32-bit application
receives 2 GB of virtual address space
in the WOW64 environment.
How do I effectively set the IMAGE_FILE_LARGE_ADDRESS_AWARE flag in my Delphi 2007 application so that I can make my 32-bit application Wow64 aware and address up to a full 4GB of memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请参阅这篇 CodeCentral 文章:在 32 位 Delphi 程序中使用超过 3 GB 内存。
在现代 Delphi 版本中,只需将编译器指令添加到 dpr:
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
See this CodeCentral article: Using more than 3 GB memory in a 32 bit Delphi program.
In modern Delphi versions just add compiler directive to the dpr:
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
使用链接器指令 $SetPEFlags:
IMAGE_FILE_LARGE_ADDRESS_AWARE
常量在 Windows.pas 中定义。不过,我不记得哪个 Delphi 版本首先包含它。在 Delphi 2007 中,您将在 " 中找到 SetPEFlags 文档PE(可移植可执行文件)标头标志(Delphi)”。
一些有用的
IMAGE_FILE_HEADER< /code>
标志
:
{$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
该映像可识别终端服务器。
Use the linker directive $SetPEFlags:
The
IMAGE_FILE_LARGE_ADDRESS_AWARE
constant is defined in Windows.pas. I don't remember which Delphi version first included it, though.In Delphi 2007, you'll find SetPEFlags documented in "PE (portable executable) header flags (Delphi)".
Some useful
IMAGE_FILE_HEADER
flags:{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} //$0020
Application can handle addresses larger than 2 GB.
{$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP} //$0800
If the image is on the network, copy it to and run it from the swap file.
{$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP} //$0400
If the image is on removable media, copy it to and run it from the swap file.
Some IMAGE_FILE_HEADER flags:
{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_NX_COMPAT} //$0100
The image is compatible with data execution prevention (DEP).
{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE} //$0040
The DLL can be relocated at load time. (aka ASLR - Address Space Layout Randomization)
{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE} //$8000
The image is terminal server aware.
请注意,编译器和 RTL 中存在一些假设,即解释为有符号 32 位整数的指针永远不会为负数。例如,编译器将不允许创建大小大于 2GB 的数据结构,并且 RTL 中的某些边界检查假设
Index + Count
Index + Count
Index + Count
Index + Count
Index + Count 0
表示加法溢出,其中Index
可以是字节数组的索引。内存管理器中可能会出现其他问题。好好测试并自行承担风险。
Note that there are assumptions baked into the compiler and RTL that pointers, interpreted as signed 32-bit integers, will never be negative. For example, the compiler will not permit creating a data structure greater than 2GB in size, and certain boundary checks in the RTL assume that e.g.
Index + Count < 0
meant the addition overflowed, whereIndex
may be an index into a byte array. Other problems may crop up in the memory manager.Test well and proceed at your own risk.
如果您这样做,请确保使用 FastMM,因为它支持 > 2GB 指针。正如 Barry Kelly 已经描述的那样,早期的 Delphi 内存管理器不能很好地工作。
If you do this, make sure to use FastMM because it supports > 2GB pointers. Earlier Delphi memory managers won't work well as Barry Kelly already described.