Как изменить размер стека для .NET-программы?

У меня есть программа, которая выполняет рекурсивные вызовы 2 миллиарда раз и переполнение стека. Я вношу изменения, а потом все равно нужно 40К рекурсивных вызовов. Так что мне, наверное, нужно несколько мегабайт стековой памяти. Я слышал, что размер стека по умолчанию составляет 1 МБ. Я пробовал искать в Интернете. Кто-то сказал, что нужно перейти к свойствам -> компоновщик ......... в Visual Studio, но я не могу его найти.

Кто-нибудь знает, как его увеличить? Также мне интересно, могу ли я установить его где-нибудь в моей программе на C #?

P.S. Я использую 32-битный winXP и 64-битный win7.


person Frank    schedule 31.03.2010    source источник


Ответы (4)


Самый простой способ установить размер стека начиная с .NET 2.0 и Win XP - это создать новый поток с желаемым размером стека: -

using System.Threading;

Thread T = new Thread(threadDelegate, stackSizeInBytes);
T.Start();

Чтобы изменить размер стека всей программы, вам нужно будет использовать editbin: -

EDITBIN.EXE /STACK:<stacksize> file.exe
person Andrew O'Reilly    schedule 31.03.2010
comment
Тем, кто выбирает путь editbin, необходимо загрузить набор инструментов Visual C ++ в установщике Visual Studio. Вы также можете указать его в шагах пост-сборки как EDITBIN.EXE /STACK:<stacksize> $(TargetName) - person Cameron Aavik; 18.03.2017
comment
@CameronAavik Добавляя к вашему комментарию, мне нужно было добавить папку инструментов SDK к моему пути, перезапустить Visual Studio, чтобы увидеть это изменение, и использовать $(TargetPath) вместо $(TargetName). - person Jamie Thomas; 07.09.2017
comment
@JamieThomas. Добавляя к своему комментарию по очереди, вместо изменения пути, вы можете включить в командную строку события после сборки: call $ (DevEnvDir) .. \ tools \ VsDevCmd.bat - person mbabramo; 27.06.2019
comment
Квалификационный мой собственный комментарий: это может не всегда работать. Установка переменной среды PATH для включения папки, содержащей editbin, будет работать. Затем команда может быть включена в элемент Exec с элементом Target с Name = PostBuild и AfterTargets = PostBuildEvent в файле .csproj. - person mbabramo; 02.10.2019

Для этого нет компилятора. Вы можете отредактируйте его постфактум, используя editbin / stack, или создайте отдельный поток для своего алгоритма и укажите больший размер стека в Конструктор потока.

При этом вы можете захотеть сгладить свою рекурсивную функцию ... Если у вас сейчас переполнение стека, трудно знать, что любой размер стека будет подходящим в долгосрочной перспективе. Это просто пластырь.

person Reed Copsey    schedule 31.03.2010

Скорее всего, вам стоит попробовать использовать циклы вместо рекурсии.

person John Boker    schedule 31.03.2010
comment
Давайте будем немного точнее: проблема не столько в рекурсии как таковой или в количестве итераций (в конце концов, после преобразования в цикл все равно будет 2 миллиарда итераций). Настоящая проблема в том, что компилятор может не генерировать хвостовые вызовы; только из-за этого рекурсия в сочетании с большим количеством итераций становится проблематичной. - person stakx - no longer contributing; 30.08.2012

Я знаю, что в VS вы можете установить произвольный размер стека (EDIT: для программ на C ++). Однако я бы посоветовал вам использовать хвостовой вызов (т.е. return MyFunc (args);), который автоматически перерабатывает пространство стека. Затем вы должны использовать какой-нибудь объект, выделенный кучей, для хранения состояния.

person Puppy    schedule 31.03.2010
comment
В общем, я не думаю, что компиляторы .NET оптимизируют хвостовой рекурсивный вызов. По крайней мере, C # и VB.NET этого не делают. - person user1172763; 01.06.2016