链接器错误:LNK1102:内存不足

本文可帮助你解决使用 x86 (32 位) 工具集生成大型项目时引发的内存不足错误。

原始产品版本:Visual Studio Professional 2010
原始 KB 编号: 2891057

症状

假设使用 x86 (32 位) 工具集生成大型项目, (已启用 ) 全程序优化 。 这意味着链接时代码生成 (LTCG) 。

在这种情况下,链接器可能会报告内存不足 (OOM) 导致生成失败的问题。

原因

出现此问题的主要原因是编译器在 LTCG 期间需要大量堆空间。 通常,链接器是磁盘输入/输出 (I/O) 绑定,使用的内存量不如编译器多。 但是,链接器确实在 LTCG 期间调用编译器。

链接器和编译器都有自己的堆管理方案。 他们没有一种机制来相互通信,以便在满足地址空间压力时提供帮助。 此外,由于编译器中的内存使用量频繁且频繁出现高峰,因此地址空间中可能存在严重的碎片,在请求少量堆空间时导致故障。

解决方案

在 Microsoft Visual Studio 2013 中,我们引入了一种机制,以确保当堆分配不成功时,编译器会将它与链接器通信,并且链接器将通过释放映射的文件来释放一些堆空间。 我们还实现了一种机制,以确保当内存压力增加时,编译器将增加堆分配中的页大小,以帮助解决碎片问题。 但是,如果接近 32 位地址空间限制,我们建议你利用 x64 (64 位) 跨编译器工具集。

在 Visual Studio 2013 中,我们还引入了 x64 交叉工具。 它包括针对 x86 和 arm 平台生成的 64 位跨编译器/链接器。 它还适用于 Visual Studio 2012 及更早版本中提供的 x86 (32 位) 交叉工具集。 本文概述用户如何使用 x64 (64 位) 交叉工具集。 如果无法移动到 Visual Studio 2013,可以在 Visual Studio 2012 及更早版本中使用以下解决方法:

  • 如果应用程序是 x64 平台的目标,请使用 x64 工具集来生成应用程序。 可以在命令行上找到 有关如何:启用 64 位 x64 托管 MSVC 工具集的说明。
  • 如果当前在 x86 操作系统上生成应用程序,请移动到 x64 操作系统。 这会将可用虚拟地址空间从 2 GB (GB) 提高到 4 GB。
  • 如果当前正在 x86 操作系统上进行编译,但无法移动到 x64 操作系统,请使用 /3GB 启动开关。 这会将可用的虚拟地址空间提高到 3 GB。

更多信息

可以在“%Install Path%\Microsoft Visual Studio 12.0\VC\bin”目录中找到两个基于 x64 的交叉工具集,如下图所示。

库窗口的屏幕截图,其中突出显示了两个基于 x64 的交叉工具集。

amd64_x86amd64_arm文件夹包含使用 x64 交叉工具集为 x86 和 arm 目标生成所需的全部内容。

对于 MSBuild 用户

如果当前在生成过程中使用 MSBuild,则可以利用名为 PreferredToolArchitecture的新项目级属性。 此属性使用户能够选择 (x86 或 x64) 用于生成应用程序的工具集。

/p:PreferredToolArchitecture=x64 argumentmsbuild 命令一起使用时,生成面向 x64 VC\bin\amd64 平台的应用程序时,将使用 x64 本机工具集 () ,在生成面向 x86 平台的应用程序时,将使用 x64 交叉工具集 (VC\bin\amd64_x86) 。

对于 Visual Studio IDE 用户

Visual Studio 集成开发环境 (IDE) 中不支持现装的 x64 交叉工具。 我们将在未来解决此问题。 但是,以下解决方法应使你能够利用 Visual Studio IDE 中的 x64 交叉工具:

  1. 启动Visual Studio 2013开发人员命令提示符。 可以在 Windows“开始”屏幕上找到开发人员命令提示符,如下所示。

    在搜索框中键入 developer 以查找开发人员命令提示。

  2. 在开发人员命令提示符下,将 属性设置为 PreferredToolArchitecture 指向要用于生成目标应用程序的工具集。

  3. 从开发人员命令提示符启动 Visual Studio (devenv) 。 现在,你应该已准备好利用交叉工具。

    VS2013 预览版窗口的“开发”命令提示符的屏幕截图。

    验证是否使用了正确的工具集的一种快速方法是创建并生成具有附加编译器标志 /Bt的应用程序。 编译器 /Bt 标志会输出有关在 C1、C1XX 和 C2 DLL 中花费的时间的详细信息。 此外,它还提供有关用于生成目标应用程序的工具集的详细信息。 可以在/Bt配置属性C++>命令行) (项目属性>页下应用标志。 在下图中,请注意正在使用 (amd64_x86) 的工具集。

    屏幕截图显示 MFCApplication3 属性页中的输出和所有选项。