C++ 设置了LargeAddressWare标志的应用程序获得的虚拟内存更少

C++ 设置了LargeAddressWare标志的应用程序获得的虚拟内存更少,c++,memory-management,operating-system,32bit-64bit,C++,Memory Management,Operating System,32bit 64bit,我有一个由一个exe和多个DLL组成的32位应用程序。exe是在设置了/LargeAddressware标志的情况下生成的。因此,我希望在64位操作系统上,我应该获得4GB的用户地址空间。但在一些64位Win 7系统上,我只能获得2GB的用户地址空间。如果需要的话,物理内存是8GB。这种行为的原因是什么?问题是,应用程序的整体必须具有大地址感知功能,因此指针将被视为无符号指针 但是,如果在“某些”系统上,您使用的某些DLL不是大的adressaware,这会使您的整个程序不知道大的地址 浏览MS

我有一个由一个exe和多个DLL组成的32位应用程序。exe是在设置了/LargeAddressware标志的情况下生成的。因此,我希望在64位操作系统上,我应该获得4GB的用户地址空间。但在一些64位Win 7系统上,我只能获得2GB的用户地址空间。如果需要的话,物理内存是8GB。这种行为的原因是什么?

问题是,应用程序的整体必须具有大地址感知功能,因此指针将被视为无符号指针

但是,如果在“某些”系统上,您使用的某些DLL不是大的adressaware,这会使您的整个程序不知道大的地址


浏览MSDN后,我发现以下内容:

在(
GlobalMemoryStatuex
())使用的
MemoryStatuex
页面上,
ullTotalVirtual
的说明如下:

对于x86处理器上的大多数32位进程,此值约为2 GB;对于在启用4 GB调优的系统上运行的支持大地址的32位进程,此值约为3 GB

4GB调优页面是:它说的是:

在64位版本的Windows上,标有IMAGE\u FILE\u LARGE\u ADDRESS\u AWARE标志的32位应用程序有4 GB的可用地址空间

安腾版Windows Server 2003:在SP1之前,32位进程只有2GB的可用地址空间

此外,如果您想确定系统支持的总内存,内存限制页()也很方便

然而,真正有用的信息来自Mark Russinowich的博客:

虽然4GB是32位客户端SKU的许可限制,但实际限制较低,并且取决于系统的芯片组和连接设备。原因是物理地址映射不仅包括RAM,还包括设备内存,x86和x64系统映射4GB地址边界以下的所有设备内存,以保持与不知道如何处理大于4GB地址的32位操作系统兼容


所以结论是,是的,这可能取决于系统的配置。也许你可以用一个表格来完成你的问题,每个系统的内存量和一些重要的系统配置设置,在这种情况下,我们可能会发现一种模式。

你能在你的可执行文件上尝试一下
DUMPBIN/HEADERS
来确认标志设置了吗?@JohnZwinck:我用
DUMPBIN/HEADERS
确认了,它说应用程序可以处理大地址。我正在使用
GlobalMemoryStatusEx
来查找总虚拟内存,如果这很重要的话,没有已知的方法可以击败LAA。这要么是代码中的一个bug,IsWow64Process()就没那么容易了。或者是环境问题,比如反恶意软件。你确定你的2Gb限制不是来自32位系统吗?(我们有一个使用相同标志的32位系统,自从64位系统问世以来,从未见过像您这样的问题。这并不意味着您的问题不是真的)。在某个地方,每个进程配置也可能有一个虚拟内存。该如何工作?exe使用32位指针,直到加载DLL(可能在数小时后),然后所有指针都更改为仅31位?根据这个链接,Raymond Chen明确表示,这个开关对DLL没有影响。