MSVC отказывается от тяжелого кода шаблона с "фатальной ошибкой C1060: компилятору не хватает места в куче"

Я пытаюсь скомпилировать некоторый относительно тяжелый код шаблона с помощью MSVC (2010), и он в итоге завершается с fatal error C1060: compiler is out of heap space,

Все это всего лишь одна единица перевода, и, в сравнении, gcc обрабатывает ее довольно легко (внутри ВМ, со значительно меньшим количеством ресурсов).

Любые намеки, что искать? Есть ли какие-либо соответствующие параметры компилятора?

6 ответов

Вы можете противостоять этому, явно добавив параметр /Zm к параметрам C/C++ вашего проекта. например, /Zm256

Смотрите эту страницу для возможного решения с опцией компилятора /Zm, как предложил Мордачай. Вместо того, чтобы использовать более высокий предел для предварительно скомпилированного заголовка, вы можете попробовать уменьшить его, чтобы в системе было больше свободной памяти.

(Сообщество VC2022 x64) Мой C1060 был вызван двумя проблемами при использовании глубокого вложения #define для создания экземпляра дерева шаблонов с большим количеством различных аргументов. /Zm[x] не помогло.

потребовалось два исправления:

  1. изменятьProject-> C++ ->Preprocessor -> Use Standard Conforming PreprocessorкYes (/Zc:preprocessor).

(без него он умер с C1060 почти сразу, без особой компиляции).

  1. после этого cl.exe компилируется, но в конечном итоге заканчивается память (около 35 ГБ в моей настройке), а затем все еще вызывает C1060. выделение большего пространства подкачки исправило это.

В случае, если кто-то столкнется с этой проблемой, вот возможное решение:

Одной из возможных причин этой ошибки является cl.exe, сталкивающийся с ограничением памяти приложения в 2 гигабайта в 32-разрядной версии Windows. Обычно Windows разделяет адресное пространство на 4 гигабайта прямо посередине, давая 2 гигабайта операционной системе и 2 гигабайта приложению. Вместо этого вы можете изменить это на 1/3. В Windows 7 и Vista выполните в командной строке следующее от имени администратора:

bcdedit / set IncreaseUserVa 3072

Затем перезагрузите компьютер. Теперь у MSVC есть 3 гигабайта вместо 2.

Это позволило мне скомпилировать проект, который не удался из-за ошибки C1060. Согласно Resource Monitor, cl.exe занимал чуть более 2 гигабайт памяти. Это не удалось бы при обычном расположении адресного пространства.

Ограничение ОС до 1 гигабайта может отрицательно сказаться на производительности при повседневном использовании вашего компьютера. Чтобы изменить разделение на 2/2, выполните следующее:

bcdedit / deletevalue IncreaseUserVa

Мне удалось устранить ошибку 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 > >>.

У меня была похожая проблема (также шаблонно-тяжелая), и я уже использовал /Zm1000 скомпилировать мой код (который работал изначально). Однако после очистки кода, деления длинных функций на более мелкие, размещения чего-либо в пространствах имен и т. Д. Компилятор выдаст сообщение об ошибке:

фатальная ошибка C1060: компилятору не хватает места в куче.

сразу после запуска, без каких-либо задержек (не похоже на то, чтобы что-то компилировать). Сначала я был в замешательстве, поскольку у меня есть 32 ГБ пространства подкачки, и в то время использовалось только около 6,1 ГБ. Я также использую операционную систему x64, поэтому для всех должно быть достаточно памяти и подкачки.

Я сослался на MSDN и узнал, что мне действительно нужно снизить /Zm800 и теперь это прекрасно работает. Насколько я понимаю, что использование всего пространства кучи для предварительно скомпилированного буфера заголовка фактически блокирует пространство памяти; так используя /Zm2000 оставил бы 32-битный компилятор без средств для динамического выделения памяти для других вещей (которые ему так или иначе нужны, что делает /Zm вариант совершенно нелепый - используйте с осторожностью).

Я использую MSVC 6.0, но надеюсь, что это поможет и в 2010 году.

Другие вопросы по тегам