本文可帮助你解决使用 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 和更低版本配合使用:
- 如果应用程序面向 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 的跨工具集,如下图所示。
amd64_x86和amd64_arm文件夹包含必须使用 x64 跨工具集为 x86 和 arm 目标构建的所有内容。
面向 MSBuild 用户
如果您当前在生成过程中使用 MSBuild,您可以利用一个名为 PreferredToolArchitecture
的新项目级属性。 此属性允许用户选择用于生成应用程序的工具集(x86 或 x64)。
在将 /p:PreferredToolArchitecture=x64 argument
与 msbuild
命令一起使用时,编译面向 x64 平台的应用程序将使用 x64 本机工具集VC\bin\amd64
,而编译面向 x86 平台的应用程序将使用 x64 跨工具集VC\bin\amd64_x86
。
对于 Visual Studio IDE 用户
Visual Studio 集成开发环境(IDE)中默认不支持 x64 跨平台工具。 我们将在未来解决此问题。 但是,以下解决方法应使你能够利用 Visual Studio IDE 中的 x64 交叉工具:
启动 Visual Studio 2013 开发人员命令提示符。 可以在 Windows 开始屏幕上找到开发人员命令提示符,如下所示。
在开发人员命令提示符处,将
PreferredToolArchitecture
属性设置为指向要用于生成目标应用程序的工具集。从开发人员命令提示符启动 Visual Studio (
devenv
)。 现在,你应该做好准备来充分利用这些跨工具。验证所使用的正确工具集的一种快速方法是创建并生成具有附加编译器标志
/Bt
的应用程序。 编译器/Bt
标志会输出有关在 C1、C1XX 和 C2 DLL 中花费时间的详细信息。 此外,它还提供有关用于生成目标应用程序的工具集的详细信息。 可以在/Bt
项目属性页下(配置属性>C++>命令行)应用该标志。 在下图中,请注意正在使用的工具集(amd64_x86)。