我正在尝试创建一个用于测试的Windows 8,32位程序。测试包括大量分配,我遇到了麻烦。操作系统以/ 3GB启动,机器有8GB和一个页面文件,程序与/LARGEADDRESSAWARE
链接,所以我不应该受内存限制。 (由于某些类型的定义方式,使用32位程序进行测试非常重要 - 例如,size_t
)。
问题是我无法从new
或VirtualAlloc
分配2GB(0x80000000)的内存。 new
抛出bad_alloc
,VirtualAlloc
NULL
返回ERROR_NOT_ENOUGH_MEMORY
。
在以前版本的Windows中,3GB地址空间意味着应用程序被赋予0x00000000到0xBFFFFFFF,而操作系统使用0xC0000000到0xFFFFFFFF(参见Richter的Programming Applications for Windows或Solomon和Russinovich的Windows Internals)。原则上,我认为这意味着我有理论空间。
如果我切换到x64,一切都按预期工作。我怀疑我错过了一些非常明显的东西,但我不确定是什么(就像地址空间中间的共享内存区域一样)。
有没有想法如何在32位计算机上执行0x80000000的分配?
答案 0 :(得分:4)
在以前版本的Windows中,3GB地址空间意味着应用程序被赋予0x00000000到0xBFFFFFFF,操作系统使用0xC0000000到0xFFFFFFFF(参见Richter的Windows编程应用程序或Solomon和Russinovich的Windows内部)。原则上,我认为这意味着我有理论空间。
Windows 8中没有任何变化。您所说的仍然是正确的。按顺序,在32位系统上,为了能够保留2GB内存块,至少需要满足以下条件:
安排前两个条件很容易,但第三个条件难以控制。您不应该假设您的进程能够在32位进程中找到2GB连续的地址空间范围。这是一个不切实际的期望。
如果您的测试系统是64位系统,那么您也应该考虑在32位系统上进行测试。例如,在64位系统上没有/ 3GB引导选项,所有大地址感知32位进程都有4GB的地址空间。当然,您仍然受我名单上第3项的约束。
答案 1 :(得分:2)
/ 3GB选项在64位操作系统上没有意义,Vista和更高版本不再支持。该选项是使用BCDEdit的现代32位版本Windows上的IncreaseUserVA,如Windows 8.因此,您实际上不太可能获得所希望的,实际上您实际上有2 GB的地址空间。哪个是你无法分配2 GB的最快解释。
32位进程在64位操作系统上获得4 GB
地址空间,因为操作系统不需要任何上层页面。您必须通过告诉操作系统您不使用不依赖指针的恶作剧(例如依赖地址的高位为零)来选择加入,需要/ LARGEADDRESSAWARE link.exe或editbin.exe选项。
这仍然不意味着您可以分配4 GB,并且您现在遇到的问题与目前获得的2 GB地址空间相同。地址空间在代码和数据之间共享。它只需要一个 DLL,它具有一个笨拙的基地址,可以将可用空间减少到两个。