【问题标题】:Force heap allocations above 4 GB强制堆分配超过 4 GB
【发布时间】:2020-03-16 10:20:02
【问题描述】:

同事将 32 位 C++ 应用程序转换为 64 位。出于测试目的,现在的想法是指示堆管理器仅返回 64 位范围内的地址。

在互联网上搜索解决方案似乎没有给出非常可靠的结果:

  • MSDN forums 建议在 CRT 初始化之前使用 VirtualAlloc()。但是,我不明白为什么不应该返回指向高地址的指针,而将底部的 4 GB 留空。

  • Raymond Chen 说,Windows 7 has a switch called Allocation­Preference 可以设置为MEM_TOP_DOWN。但是,这适用于整个系统,因此需要重新启动,这很不方便。 (也描述了on MSDN)。

我在应用程序验证器中进行了挖掘,并在 Heaps 条目的属性中发现了一些有趣的选项:

如您所见,我修改了 SizeStartSizeEnd 以及 AddrStartAddrEnd

不幸的是,

  1. 这些文本框不接受 64 位地址
  2. 这些设置似乎没有效果

虽然地址高于输入的值,但堆的大小没有改变:

Termination on corruption : ENABLED
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
000001e0aa590000 00000002    2040   1528   2040      3     1     2    0      0      
000001e0aa440000 00001002    1080    248   1080      2     2     2    0      0      
000001e0aa410000 00008000      64      4     64      2     1     1    0      0      
000001e0aa520000 00001002    1080    104   1080      1     2     2    0      0      
000001e0af2f0000 00001002      60     60     60      6     1     1    0      0      
-------------------------------------------------------------------------------------

这些应用程序验证器设置是否仍然有效?如何成功申请?

【问题讨论】:

  • 有趣的问题,我怀疑单个堆分配被限制在一些名义上的限制(可能是 4GB,但我找不到任何参考),但堆池限制取决于操作系统版本。如果设置该标志并重新启动太痛苦,您可以执行 Raymond 的建议并在 init 上保留前 4GB 以强制进一步分配到上述 4GB 地址空间。我也不感到惊讶,其中一些选项和标志可能不起作用,最新版本的应用程序验证器对我不起作用,必须使用旧版本
  • 在 Win8.1 或更高版本上运行是最简单的方法,这些版本总是分配在 4GB 以上。看起来你有 Win10,所以你很高兴。
  • @MarekR:嗯,曾经有一段时间人们滥用指针的一部分来传输指针最高位置的附加位。这就是我们拥有 LargeAddressAware 等所有东西的原因。

标签: c++ windows 64-bit application-verifier


【解决方案1】:

正如@HansPassant 在 cmets 中提到的那样,Windows 8 分配的内存超出了 4 GB 的限制。这是因为 64 位应用程序默认使用/HIGHENTROPYVA 标志编译,如Raymond Chen's "The old new thing" blog post 中所述。

对于 Windows 7,想法是使用VirtualQuery(),检查MEM_FREE,然后使用VirtualAlloc() 分配所有这些区域,您可以在其中传递要分配的地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-26
    • 2012-04-04
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 2012-10-10
    相关资源
    最近更新 更多