Максимальный размер стека потока .NET? - PullRequest
13 голосов
/ 01 апреля 2011

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

public Thread( ThreadStart start, int maxStackSize )

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

Ответы [ 2 ]

27 голосов
/ 01 апреля 2011

Для справки, это соответствует категории Рэймонда Чена «если вам нужно знать, то вы делаете что-то не так».

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

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

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

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

3 голосов
/ 01 апреля 2011

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

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

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

...