【问题标题】:Memory allocation in MSVC++ 2019MSVC++ 2019 中的内存分配
【发布时间】:2021-08-10 15:15:23
【问题描述】:

我有一个关于内存分配的问题,尤其是在使用 MSVC2019 时。

我有一个编译为 x64 的 C++ 程序。 通过调试我看到,分配变量会产生非常高的指针地址,指向前 4GB 地址空间(32 位)上的位置。如果我在任务管理器中检查程序,我发现它只使用了大约 30-50MB 的内存。

实际上4GB以下的整个地址空间都没有使用时,变量没有分配到虚拟内存空间的下部是什么原因?

我希望分配从低地址开始,直到使用的第一个 4GB 空间,不需要分配空间。

为什么这对我来说很有趣: 我有一个包含超过 15 年历史的 C++ 代码的大型 SW,它并非到处都准备好成为 64 位,在许多地方它将指针转换为 32 位类型,因此指针被损坏。最初的作者很可能假设指针是 32 位的。当编译为 64 位时,实际上应该也是如此,因此程序没有使用太多内存,内存使用量不会增长超过 4GB。而且似乎使用 2010 年的编译器编译时,不会出现这个问题,可能是那个时候内存分配导致地址在第一个 4GB 块中,即使是为 x64 编译的。

我的问题是: 这种分配策略会以某种方式影响 MSVC++ 2019 吗?例如。指示他的编译器/链接器/内存管理器优先分配前 32 位空间,直到不再需要?或者,为内存管理器提供的虚拟地址空间设置大小限制,例如。通过设置为 2GB,我可以实现永远不会有任何指针指向超过 4GB 的已分配块。这样,假设指针为 32 位,旧代码将在强制转换操作中继续存在。

我已经尝试在链接器选项中将高内存感知设置为 NO,并检查了堆参数,但它们都没有帮助。

谢谢!

【问题讨论】:

  • 请花一些时间刷新the help pages,尤其是名为"What topics can I ask about here?""What types of questions should I avoid asking?" 的部分。也请使用tour 并阅读How to Ask 的好问题。最后请阅读this question checklist
  • 您不会通过确保您的程序使用可以用 32 位枚举的内存来解决问题。实际上,使用 32 位的演员阵容不正确的可能性很高
  • 内存地址是虚拟的,它们不直接映射到物理地址。这就是虚拟内存的工作原理。
  • 还阅读有关“地址空间布局随机化”的概念,以进一步了解为什么程序最终从所有可用地址空间中分配内存是一件好事。
  • 问题不是为什么它是一件好事,而是如何禁用这个好事并回到旧的方式。并非所有好的新事物在每种情况下都对每个人都有好处,我正在寻找是否有办法选择退出,并在 MSVC++2019 上获得与在 MSVC++2010 上相同的行为。如果没有,那么我们唯一的办法就是修复代码,或者切换到 32 位。

标签: c++ pointers memory-management visual-c++-2019


【解决方案1】:

如果您的程序假定指针是 32 位的,那么您只需要针对 32 位进行编译,直到您使用 ifdef 来检查您正在编译的对象的正确声明。

只需从下拉列表中选择 x86 而不是 x64 作为解决方法,直到您对旧代码进行现代化改造。

您可以使用大地址空间做更多事情,而且由于操作系统将这些映射到物理内存的部分,编译器只是选择了将地址空间的不同部分分开以用于不同目的的好处。

有一些方法可以创建自定义堆并在特定地址空间可用时在特定地址空间上分配内容,但是与正确分配正确大小相比,将这些处理到代码中可能需要同样长的时间并且倒退。

【讨论】:

    【解决方案2】:

    欢迎来到虚拟内存的世界!事实上,为了动态分配内存,标准库请内核提供它。并且只有内核负责分配给程序的虚拟地址。由于每个进程都有自己的虚拟地址转换器,因此可以为多个进程分配相同的虚拟地址。 作为程序员,您永远不应该担心这一点。使用内核给你的内存地址并继续。如果假设指针不能超过 32 位,则必须使用遗留代码,那么您不应该在 64 位模式下编译它,而只能在 32 位模式下编译。

    【讨论】:

    • 如果内核负责提供虚拟内存地址,那么在64位模式下使用MSVC++2010编译相同的代码时,指针怎么可能在4GB以下?它是多年前使用这种 64 位设置编译的,我们从未收到问题报告。当我们现在使用 MSVC++2019 编译时,它会立即遇到指针截断。这就是为什么我的第一个假设是,自 2010 年以来 MSVC++ 编译器中可能发生了一些变化,影响了分配的工作方式,也许有一个编译器选项告诉“像你在 2010 年之前那样做”。
    • @RobertV: 可能是底层操作系统变化引起的……
    猜你喜欢
    • 1970-01-01
    • 2016-05-03
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多