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] не помогло.
потребовалось два исправления:
- изменять
Project-> C++ ->Preprocessor -> Use Standard Conforming Preprocessor
кYes (/Zc:preprocessor)
.
(без него он умер с C1060 почти сразу, без особой компиляции).
- после этого 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 году.