【问题标题】:MSVC gives up on template heavy code with "fatal error C1060: compiler is out of heap space"MSVC 放弃使用“致命错误 C1060:编译器堆空间不足”的模板繁重代码
【发布时间】:2011-06-04 07:53:46
【问题描述】:

我正在尝试使用 MSVC (2010) 编译一些相对模板繁重的代码,它最终以 fatal error C1060: compiler is out of heap space 退出。

整个事情只是一个翻译单元,相比之下,gcc 很容易处理它(在 VM 中,资源要少得多)。

任何提示要寻找什么?有没有相关的编译器选项?

【问题讨论】:

  • 不要使用荒谬的模板?
  • 我在带有非常简单模板的旧版 MSVC 上遇到了这样的错误,但这是由于我的代码中的错误,显然不是你的情况
  • 您可能在模板实例化中有无限(深度)递归
  • 你试过 VS 2010 SP1 beta 吗?也许它解决了这个问题(尽管它可能是无限递归,正如 Gene 所暗示的)
  • @Gene:如前所述,它是用 gcc 编译的,所以事实并非如此。我认为 MSVC 对于嵌套太深的模板也有适当的信息。

标签: c++ visual-c++ templates compiler-errors ice


【解决方案1】:

可能可以通过将 /Zm 选项显式添加到项目的 C/C++ 选项来解决此问题。例如/Zm256

【讨论】:

  • 其实这可能不适用于你?试试看,但它被记录为“预编译头内存”。在我们设置此值之前,我们遇到了类似的错误。但你的情况可能不同?
  • 试过 /Zm2000,但没有帮助 :P 谢谢。
【解决方案2】:

请参阅this 页面,了解使用 /Zm 编译器选项的可能解决方案,正如 Mordachai 建议的那样。 您可能想尝试降低它,而不是对预编译头使用更高的限制,以便系统有更多的可用内存。

【讨论】:

    【解决方案3】:

    通过减少模板上的模板参数数量,我能够使用适度的模板代码解决 C1060 错误。例如,如果 Foo 需要三种类型:

    template< typename T1, typename T2, typename T3 > struct Foo
    {
      T1 t1;
      T2 t2;
      T3 t3;
    };
    
    Foo< int, char, bool > foo;
    

    然后将类型封装到单个结构中,并将该结构用作参数。

    template< typename T_ARG > struct Foo
    {
      typename T_ARG::T1 t1;
      typename T_ARG::T2 t2;
      typename T_ARG::T3 t3;
    };
    
    struct FooArgs
    {
      typedef int  T1;
      typedef char T2;
      typedef bool T3;
    };
    
    Foo< FooArgs > foo;
    

    如果需要专业化,请考虑:

    • 将特殊行为推入策略并继承它们。
    • 在参数列表中保留您需要专门研究的参数。
    • 将类型链接到类型列表中。 Foo > > >.

    【讨论】:

      【解决方案4】:

      如果有人遇到这个问题,这里有一个可能的解决方案:

      此错误的一个潜在原因是 cl.exe 违反了 32 位版本的 Windows 中的 2 gig 应用程序内存限制。通常,Windows 在中间分割 4 gig 地址空间,为操作系统提供 2 gig,为应用程序提供 2 gig。您可以改为将其更改为 1/3 拆分。在 Windows 7 和 Vista 上,以管理员身份在命令提示符下运行以下命令:

      bcdedit /set increaseUserVa 3072

      然后重新启动计算机。现在 MSVC 有 3 个 gig 可供使用,而不是 2 个。

      这样做只是让我编译了一个由于错误 C1060 而失败的项目。根据 Resource Monitor 的说法,cl.exe 消耗的内存略高于 2 gig。在常规地址空间安排下它会失败。

      将操作系统限制为仅 1 gig 可能会对日常使用计算机时的性能产生不利影响。要将拆分改回 2/2,请运行以下命令:

      bcdedit /deletevalue 增加用户变量

      【讨论】:

        【解决方案5】:

        我遇到了类似的问题(模板也很重),并且我已经在使用 /Zm1000 编译我的代码(最初有效)。但是,在清理代码、将长函数拆分为更小的函数、将内容放入命名空间 / 等之后,编译器会吐出错误消息:

        致命错误 C1060:编译器堆空间不足。

        在开始之后,没有任何延迟(实际上似乎没有编译任何东西)。起初,我很困惑,因为我有 32 GB 的交换空间,而当时只使用了大约 6.1 GB。我也在运行 x64 操作系统,所以应该有足够的内存和交换空间。

        我参考了MSDN,发现我实际上需要降低/Zm800,现在效果很好。我的理解是,为预编译的头缓冲区占用所有堆空间实际上锁定了内存空间;所以使用/Zm2000 将使32 位编译器无法为其他东西动态分配内存(它也需要它,使得/Zm 选项完全荒谬 - 谨慎使用)。

        我正在使用 MSVC 6.0,但我希望这对 2010 年也有帮助。

        【讨论】:

          猜你喜欢
          • 2014-07-17
          • 1970-01-01
          • 2017-03-10
          • 2018-12-21
          • 1970-01-01
          • 2021-03-19
          • 1970-01-01
          • 1970-01-01
          • 2020-06-13
          相关资源
          最近更新 更多