如何解决 Visual Studio 编译器崩溃

Posted

技术标签:

【中文标题】如何解决 Visual Studio 编译器崩溃【英文标题】:How to work around Visual Studio Compiler crashes 【发布时间】:2010-11-26 04:38:29 【问题描述】:

我们有一个大型 Visual Studio 2005 C++/Mfc 解决方案,1 个项目包含大约 1300 个源文件(大约 650 个 .h 和 650 个 .cpp 文件)。我们还使用 Boost 和其他一些库(COM:MSXML、Office)。

最近,我添加了一些 boost::multi_index 实例来加快速度。这一切大部分时间都在编译。但是现在,当我进行完整(发布)重建时,我会在几个模块处遇到编译器崩溃。

Fatal Error C1060: "compiler is out of heap space"

我已经尝试减少预编译头文件中的包含(删除了除了标准 MFC 头文件之外的几乎所有内容)。另外,我删除了编译器选项 /Zm200(我们之前需要它来编译预编译的头文件)。

奇怪的是:当我在编译器崩溃后按 F7(构建)时,构建过程继续没有任何问题(或者至少直到下一次编译器崩溃,我再次按 F7)。但是,如果能够在没有任何中断的情况下进行完整的构建,那就太好了。

我可以影响各个模块的构建顺序吗?这样,我可以将“有问题”的模块放在流程的开头(并希望崩溃不会转移到其他模块)。

顺便说一句:完整的构建大约需要 90 分钟。


更新:

感谢您的回答。我能够摆脱编译器崩溃并显着减少编译时间。这是我所做的:

    我从预编译的头文件中删除了所有包含,只保留了标准的 windows/mfc 头文件。这迫使我在其他模块中添加更多包含,但最终所有内容都包含在需要的地方。当然,这一步增加了编译时间,但让我在下一步中更有效率。 我安装了ProFactors IncludeManager的试用版。项目详细视图可以导出到 Excel,其中可以很快发现要包含在预编译头文件中的瓶颈和候选对象。 大部分编译时间都浪费在一些头文件上,这些头文件包括一堆其他头文件(包括更多...)。我不得不使用前向声明来摆脱一些讨厌的依赖。此外,我将一些类/函数从关键头文件中移到了它们自己的模块中。 What to put in precompiled header? (MSVC) 帮助我正确获取了预编译头文件中的包含。我添加了 STL、Boost、Windows 标头。然后添加我们自己的(或多或少稳定、优化的)头文件,以及资源头文件。 我重复了步骤 3 和 4 几次,始终使用 IncludeManager 检查新候选人。 步骤 1 到 5 将编译时间(发布模式)从 90 分钟缩短到大约 45 分钟。 我禁用了所有内容的浏览信息生成,因为我们似乎没有使用它(而且我找不到任何关于它真正有用的信息......)。这又切断了 6 分钟的构建过程。 我在 C++ 编译器命令中添加了 /MP(多处理器支持)开关。现在重建时间减少到 22 分钟。这一切都是在单核 PC 上完成的。 我将整个解决方案移至双核 PC。在那里重建项目需要 16 分钟。 创建调试版本快 5 分钟: 单核机17分钟, 11 分钟在双核机器上。

更新 2:

上面我提到“单核机”,实际上是指速度较慢的双核机。

【问题讨论】:

Above, where I mention "single core machine", actually a slower dual core machine is meant.lol 【参考方案1】:

如果 1300 个文件需要这么长时间来编译,那么你包含了太多不必要的头文件。我猜人们已经将一堆头文件剪切并粘贴到 CPP 文件中,而没有考虑他们实际需要哪些头文件,以便在不应该包含的时候包含它们的负载。我也猜想你没有向前声明你应该在哪里的类。

我建议您需要花一些时间浏览您的项目并删除不必要的#include。我怀疑这将解决您的内存不足问题并缩短您的编译时间。

【讨论】:

是的,项目中有很多包含,我也在努力减少这些。是否有工具可以帮助我识别“关键”模块(包括大多数其他模块)? 试试 Doxygen (stack.nl/~dimitri/doxygen)。引用其手册:# 为每个包含至少一个其他文件的文档文件生成一个包含依赖关系图。此功能目前仅支持 html 和 RTF。 # 还会生成一个反向包含依赖关系图,显示一个(头)文件,其他文件包含它。只需确保 Doxygen 的配置文件(称为 Doxyfile)没有设置了 HIDE_UNDOC_RELATIONS,以便您获得所有类/项目的输出。【参考方案2】:

我必须同意 Goz,看看 this (SO) post 以了解帮助删除冗余头文件的方法。

我们的 C++ 解决方案大小如此粗略,过去编译需要 50 分钟,通过仔细分析头文件,我们将编译时间缩短到了 8 分钟。

【讨论】:

谢谢。我还安装了 ProFactor IncludeManager。现在如何识别最关键的模块?有推荐的方法吗? 我们已经有一段时间没有愤怒地这样做了,但我认为我们首先查看了项目包含和项目详细信息结构,并尝试查看是否有任何明显错误(意外包含) ,然后我们向下移动到我们知道编译需要很长时间的关键文件,并查看对这些文件的构建影响。我认为,一旦我们理清了 stdafx.h 中应该和不应该的内容,就会产生最大的不同。如果 stdafx.h 包含在大量文件中,那么您实际上可能希望在其中包含更多内容,然后需要很长时间才能编译。【参考方案3】:

IncrediBuild(用于 VC++ 的分布式构建系统)除了省时还有一个额外的有用功能。如果远程机器无法返回结果,它将自动重新启动编译。因此,您应该能够在 5 或 10 分钟内获得完整的构建,而不会发生崩溃。

【讨论】:

以上是关于如何解决 Visual Studio 编译器崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何用visual studio2010编译已经写好的C#的源代码

如何用pcl配置visual studio 2010

如何只用visual c++编译器而不安装visual studio

如何解决此 Visual Studio 编译器 BUG?

为啥 Roslyn 在尝试重写此 lambda 时会崩溃? (Visual Studio 2015 更新 1)

Visual Studio 控制台程序在 control-c 后崩溃