Patrzysz na faceta, który dokonał tego wyboru. David Cutler i jego zespół wybrali jeden megabajt jako domyślny rozmiar stosu. Nie ma to nic wspólnego z .NET czy C #, zostało to ustalone podczas tworzenia systemu Windows NT. Jeden megabajt jest tym, co wybiera, gdy nagłówek EXE programu lub wywołanie winapi CreateThread () nie określa jawnie rozmiaru stosu. Co jest normalne, prawie każdy programista pozostawia systemowi operacyjnemu wybór rozmiaru.
Ten wybór prawdopodobnie poprzedza projekt Windows NT, historia jest o wiele zbyt niejasna. Byłoby miło, gdyby Cutler napisał o tym książkę, ale nigdy nie był pisarzem. Był niezwykle wpływowy na sposób działania komputerów. Jego pierwszym projektem systemu operacyjnego był RSX-11M, 16-bitowy system operacyjny dla komputerów DEC (Digital Equipment Corporation). Ma to duży wpływ na CP / M Gary'ego Kildalla, pierwszy przyzwoity system operacyjny dla 8-bitowych mikroprocesorów. Co mocno wpłynęło na MS-DOS.
Jego kolejnym projektem był VMS, system operacyjny dla 32-bitowych procesorów z obsługą pamięci wirtualnej. Bardzo udany. Jego następny został odwołany przez DEC mniej więcej w czasie, gdy firma zaczęła się rozpadać, nie będąc w stanie konkurować z tanim sprzętem PC. Cue Microsoft, złożyli mu ofertę, której nie mógł odmówić. Przyłączyło się też wielu jego współpracowników. Pracowali na VMS v2, lepiej znanym jako Windows NT. DEC był tym zdenerwowany, pieniądze zmieniły właściciela, aby to uregulować. Nie wiem, czy VMS wybrał już jeden megabajt, ale znam RSX-11 wystarczająco dobrze. Nie jest to nieprawdopodobne.
Dość historii. Jeden megabajt to dużo , prawdziwy wątek rzadko zużywa więcej niż kilka garści kilobajtów. Więc megabajt jest raczej marnotrawstwem. Jest to jednak rodzaj marnotrawstwa, na jaki można sobie pozwolić w systemie operacyjnym pamięci wirtualnej ze stronicowaniem na żądanie, ponieważ megabajt to tylko pamięć wirtualna . Tylko numery do procesora, po jednym na każde 4096 bajtów. W rzeczywistości nigdy nie używasz pamięci fizycznej, pamięci RAM w komputerze, dopóki nie zajmiesz się tym.
W programie .NET jest on wyjątkowo nadmierny, ponieważ pierwotnie wybrano rozmiar jednego megabajta, aby pomieścić programy natywne. Które mają tendencję do tworzenia dużych ramek stosu, przechowując również ciągi i bufory (tablice) na stosie. Niesławny z tego, że jest wektorem ataku złośliwego oprogramowania, przepełnienie buforu może manipulować programem za pomocą danych. Nie sposób, w jaki działają programy .NET, łańcuchy i tablice są przydzielane na stercie GC, a indeksowanie jest sprawdzane. Jedynym sposobem przydzielenia miejsca na stosie za pomocą C # jest użycie niebezpiecznego słowa kluczowego stackalloc .
Jedynym nietrywialnym zastosowaniem stosu w .NET jest jitter. Używa stosu twojego wątku do kompilacji MSIL na czas do kodu maszynowego. Nigdy nie widziałem ani nie sprawdzałem, ile miejsca zajmuje, raczej zależy to od natury kodu i tego, czy optymalizator jest włączony, ale kilka dziesiątek kilobajtów to zgadywanie. W przeciwnym razie ta witryna otrzymała swoją nazwę, przepełnienie stosu w programie .NET jest fatalne. Za mało miejsca (mniej niż 3 kilobajty), aby nadal niezawodnie JIT był dowolny kod, który próbuje przechwycić wyjątek. Kaboom to desktop jest jedyną opcją.
Wreszcie, program .NET robi coś nieproduktywnego ze stosem. Środowisko CLR zatwierdzi stos wątku. To drogie słowo, które oznacza, że nie tylko rezerwuje rozmiar stosu, ale także zapewnia, że miejsce jest zarezerwowane w pliku stronicowania systemu operacyjnego, dzięki czemu stos można zawsze zamienić w razie potrzeby. Niepowodzenie wykonania jest błędem krytycznym i bezwarunkowo kończy program. Dzieje się tak tylko na komputerze z bardzo małą pamięcią RAM, który uruchamia zbyt wiele procesów, taka maszyna zamieni się w melasę, zanim programy zaczną umierać. Możliwy problem 15+ lat temu, nie dzisiaj. Programiści, którzy dostrajają swój program, aby zachowywał się jak samochód wyścigowy F1, używają <disableCommitThreadStack>
elementu w swoim pliku .config.
Fwiw, Cutler nie przestawał projektować systemów operacyjnych. To zdjęcie zostało zrobione podczas pracy na Azure.
Aktualizacja, zauważyłem, że .NET już nie zatwierdza stosu. Nie jestem pewien, kiedy i dlaczego to się stało, minęło zbyt dużo czasu, odkąd sprawdzałem. Domyślam się, że ta zmiana projektu nastąpiła gdzieś w okolicy .NET 4.5. Całkiem rozsądna zmiana.
Thread
konstruktora. ALE, to nasuwa pytanie, dlaczego potrzebujesz większego stacka?