Максимальный размер стека в .NET?

Каков максимальный размер стека, разрешенный для потока в С#.NET 2.0? Кроме того, зависит ли это значение от версии CLR и/или битности (32 или 64) базовой ОС? Я рассмотрел следующие ресурсы msdn1 и msdn2

public Thread( ThreadStart start, int maxStackSize )

Единственная информация, которую я вижу, - это размер по умолчанию 1 мегабайт и выше, если maxStackSize равен '0', будет использоваться максимальный размер стека по умолчанию, указанный в заголовке для исполняемого файла, какое максимальное значение, которое мы можем изменить значение в заголовке до? Также целесообразно это сделать? Спасибо.

Ответы

Ответ 1

Для записи это соответствует категории Raymond Chen "если вам нужно знать, что вы делаете что-то не так".

Размер стека по умолчанию для потоков с 64-битным кодом составляет 4 мегабайта, 1 мегабайт для 32-битного кода. Хотя конструктор Thread позволяет передавать целочисленное значение до int.MaxValue, вы никогда не получите это на 32-битной машине. Стек должен соответствовать доступному отверстию в адресном пространстве виртуальной памяти, которое обычно заканчивается на ~ 600 МБ на раннем этапе процесса. Быстро уменьшается, когда вы выделяете память и фрагментируете адресное пространство.

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

Самый маленький стек, который .NET позволяет вам выбрать, составляет 250 КБ. Он молча округляет его, если вы передадите меньшее значение. Необходимо, потому что и джиттеру, и сборщику мусора требуется пространство стека, чтобы выполнить свою работу. Опять же, делать это должно быть совершенно ненужным. Если вы сочтете это так, потому что у вас много потоков и потребляет всю виртуальную память со своими стеками, то у вас слишком много потоков. StackOverflowException - одно из самых отвратительных исключений, которые вы можете получить. Процесс смерти является немедленным и невозвратным.

Размер стека для основного потока определяется опцией в заголовке EXE. У компилятора нет возможности изменить его, вы должны использовать editbin.exe/stack для исправления заголовка .exe.

Ответ 2

Я не знаю, что такое максимум, но MSDN говорит о том, следует ли вам это делать или нет:

Избегайте использования этой перегрузки конструктора. Размер стека по умолчанию, используемый перегрузкой конструктора ThreadStart, является рекомендуемым размером стека для потоков. Если поток имеет проблемы с памятью, наиболее вероятной причиной является ошибка программирования, такая как бесконечная рекурсия.

У меня никогда не было StackOverflow на С#, который не был вызван бесконечной рекурсией. Если бы действительно был случай, когда рекурсия дошла до этой глубины, я бы подумал о замене ее итерацией.