Ответ 1
Вы смотрите на парня, который сделал этот выбор. Дэвид Катлер и его команда выбрали один мегабайт в качестве размера стека по умолчанию. Ничего общего с .NET или С#, это было прибито, когда они создали Windows NT. Один мегабайт - это то, что он выбирает, когда заголовок EXE программы или вызов winapi CreateThread() не задают размер стека явно. Что является нормальным способом, почти любой программист оставляет его ОС для выбора размера.
Этот выбор, вероятно, предшествует дизайну Windows NT, история слишком мутная об этом. Было бы хорошо, если бы Катлер написал бы книгу об этом, но он никогда не был писателем. Он был чрезвычайно влиятелен на то, как работают компьютеры. Его первый дизайн ОС - RSX-11M, 16-разрядная операционная система для компьютеров DEC (Digital Equipment Corporation). Это сильно повлияло на Gary Kildall CP/M, первую достойную ОС для 8-битных микропроцессоров. Что сильно повлияло на MS-DOS.
Следующим его проектом стала VMS, операционная система для 32-разрядных процессоров с поддержкой виртуальной памяти. Очень успешный. Его следующий был отменен DEC примерно в то время, когда компания начала распадаться, не имея возможности конкурировать с дешевым оборудованием для ПК. Кий Microsoft, они сделали ему предложение, от которого он не мог отказаться. К нему присоединились и многие из его коллег. Они работали над VMS v2, более известной как Windows NT. DEC расстроилась из-за этого, деньги сменили руки, чтобы урегулировать это. Является ли VMS уже одним мегабайтом, я не знаю, я знаю только RSX-11. Это маловероятно.
Достаточно истории. Один мегабайт - это лот, реальная нить редко потребляет больше, чем несколько горстей килобайт. Таким образом, мегабайт на самом деле довольно расточительный. Тем не менее, это те виды отходов, которые вы можете себе позволить в оперативной системе виртуальной памяти с запросами по требованию, что мегабайт - это просто виртуальная память. Просто номера процессора, по одному на каждые 4096 байт. Вы никогда не используете физическую память, оперативную память в машине, пока вы на самом деле не обратитесь к ней.
Это лишнее чрезмерное значение в программе .NET, потому что один мегабайт был первоначально выбран для размещения собственных программ. Они, как правило, создают большие стековые фреймы, сохраняя строки и буферы (массивы) в стеке. Печально известный как вектор атаки вредоносного ПО, переполнение буфера может манипулировать программой данными. Не так, как работают .NET-программы, строки и массивы выделяются на куче GC и проверяется индексация. Единственный способ выделить пространство в стеке с помощью С# - это небезопасное ключевое слово stackalloc.
Единственное нетривиальное использование стека в .NET - это дрожание. Он использует стек вашего потока для компиляции MSIL для компиляции MSIL в машинный код. Я никогда не видел и не проверял, сколько места он требует, скорее зависит от характера кода и от того, включен ли оптимизатор, но несколько десятков килобайт - это грубое предположение. В противном случае, как этот сайт получил свое имя, переполнение стека в .NET-программе является довольно фатальным. Недостаточно свободного места (менее 3 килобайт), чтобы все еще надежно использовать JIT любой код, который пытается поймать исключение. Kaboom для настольных компьютеров является единственным вариантом.
И последнее, но не менее важное:.NET-программа делает что-то довольно непродуктивное со стеком. CLR зафиксирует стек потока. Это дорогое слово, что означает, что он не просто резервирует размер стека, но также гарантирует, что пространство зарезервировано в файле подкачки операционной системы, поэтому при необходимости стек всегда может быть заменен. Неспособность совершить является фатальной ошибкой и безоговорочно завершает программу. Это происходит только на машине с очень маленькой ОЗУ, которая запускает полностью слишком много процессов, такая машина превратится в патоку, прежде чем программы начнут умирать. Возможная проблема 15 лет назад, а не сегодня. Программисты, которые настраивают свою программу, чтобы действовать как гоночный автомобиль F1, используют <disableCommitThreadStack>
в своем файле .config.
Fwiw, Катлер не прекратил разработку операционных систем. Эта фотография была сделана, когда он работал над Azure.
Обновление, я заметил, что .NET больше не выполняет стек. Не совсем точно, когда и почему это произошло, я слишком долго не проверял. Я предполагаю, что это изменение дизайна произошло где-то около .NET 4.5. Довольно разумные изменения.