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

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

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

现象

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

在此情景中,链接器可能会报告导致构建失败的内存不足(OOM)问题。

原因

此问题主要是因为编译器在 LTCG 期间所需的大量堆空间。 通常,链接器是磁盘输入/输出(I/O)绑定的,并且不会使用与编译器一样多的内存。 但是,链接器在 LTG 期间会调用编译器。

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

决议

在 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 和更低版本配合使用:

详细信息

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

“Bin”窗口的屏幕截图,其中突出显示了两个基于 x64 的跨工具集。

amd64_x86amd64_arm文件夹包含必须使用 x64 跨工具集为 x86 和 arm 目标构建的所有内容。

面向 MSBuild 用户

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

在将 /p:PreferredToolArchitecture=x64 argumentmsbuild 命令一起使用时,编译面向 x64 平台的应用程序将使用 x64 本机工具集VC\bin\amd64,而编译面向 x86 平台的应用程序将使用 x64 跨工具集VC\bin\amd64_x86

对于 Visual Studio IDE 用户

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

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

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

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

  3. 从开发人员命令提示符启动 Visual Studio (devenv)。 现在,你应该做好准备来充分利用这些跨工具。

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

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

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