Stai guardando il ragazzo che ha fatto quella scelta. David Cutler e il suo team hanno selezionato un megabyte come dimensione dello stack predefinita. Niente a che vedere con .NET o C #, questo è stato risolto quando hanno creato Windows NT. Un megabyte è ciò che sceglie quando l'intestazione EXE di un programma o la chiamata winapi CreateThread () non specifica esplicitamente la dimensione dello stack. Che è il modo normale, quasi tutti i programmatori lasciano che sia il sistema operativo a scegliere la dimensione.
Questa scelta probabilmente è precedente al design di Windows NT, la storia è troppo oscura su questo. Sarebbe bello se Cutler scrivesse un libro a riguardo, ma non è mai stato uno scrittore. È stato straordinariamente influente sul modo in cui funzionano i computer. Il suo primo progetto di sistema operativo è stato RSX-11M, un sistema operativo a 16 bit per computer DEC (Digital Equipment Corporation). Ha fortemente influenzato il CP / M di Gary Kildall, il primo sistema operativo decente per microprocessori a 8 bit. Che ha fortemente influenzato MS-DOS.
Il suo progetto successivo fu VMS, un sistema operativo per processori a 32 bit con supporto di memoria virtuale. Molto successo. Il suo prossimo è stato cancellato dal DEC nel periodo in cui la società ha iniziato a disintegrarsi, non essendo in grado di competere con hardware per PC a basso costo. Cue Microsoft, gli hanno fatto un'offerta che non poteva rifiutare. Anche molti dei suoi colleghi si sono uniti. Hanno lavorato su VMS v2, meglio conosciuto come Windows NT. Il DEC si è arrabbiato, i soldi sono passati di mano per risolverlo. Se VMS ha già scelto un megabyte è qualcosa che non so, conosco solo abbastanza bene RSX-11. Non è improbabile.
Abbastanza storia. Un megabyte è molto , un vero thread raramente consuma più di un paio di manciate di kilobyte. Quindi un megabyte è in realtà piuttosto dispendioso. Tuttavia, è il tipo di spreco che puoi permetterti su un sistema operativo di memoria virtuale con paging a richiesta, quel megabyte è solo memoria virtuale . Solo numeri per il processore, uno ogni 4096 byte. Non usi mai la memoria fisica, la RAM nella macchina, fino a quando non la indirizzi.
È eccessivo in un programma .NET perché la dimensione di un megabyte è stata originariamente scelta per ospitare programmi nativi. Che tendono a creare frame di stack di grandi dimensioni, memorizzando anche stringhe e buffer (array) nello stack. Famoso per essere un vettore di attacco malware, un buffer overflow può manipolare il programma con i dati. Non è il modo in cui funzionano i programmi .NET, le stringhe e gli array vengono allocati sull'heap GC e l'indicizzazione viene controllata. L'unico modo per allocare spazio nello stack con C # è con la parola chiave stackalloc non sicura .
L'unico utilizzo non banale dello stack in .NET è il jitter. Usa lo stack del tuo thread per compilare MSIL just-in-time in codice macchina. Non ho mai visto o controllato quanto spazio richiede, piuttosto dipende dalla natura del codice e se l'ottimizzatore è abilitato o meno, ma un paio di decine di kilobyte è un'ipotesi approssimativa. Che è altrimenti il modo in cui questo sito web ha preso il nome, un overflow dello stack in un programma .NET è abbastanza fatale. Non c'è abbastanza spazio rimasto (meno di 3 kilobyte) per JIT ancora in modo affidabile qualsiasi codice che tenta di catturare l'eccezione. Kaboom to desktop è l'unica opzione.
Ultimo ma non meno importante, un programma .NET fa qualcosa di piuttosto improduttivo con lo stack. Il CLR eseguirà il commit dello stack di un thread. È una parola costosa che significa che non si limita a riservare la dimensione dello stack, ma si assicura anche che lo spazio sia riservato nel file di paging del sistema operativo in modo che lo stack possa sempre essere sostituito quando necessario. L'impossibilità di eseguire il commit è un errore irreversibile e termina un programma incondizionatamente. Ciò accade solo su macchine con poca RAM che esegue troppi processi, una macchina del genere si sarà trasformata in melassa prima che i programmi inizino a morire. Un possibile problema più di 15 anni fa, non oggi. I programmatori che ottimizzano il loro programma per comportarsi come un'auto da corsa di F1 utilizzano l' <disableCommitThreadStack>
elemento nel loro file .config.
Fwiw, Cutler non ha smesso di progettare sistemi operativi. Quella foto è stata fatta mentre lavorava su Azure.
Aggiornamento, ho notato che .NET non esegue più il commit dello stack. Non sono esattamente sicuro di quando o perché sia successo, è passato troppo tempo da quando ho controllato. Immagino che questa modifica al design sia avvenuta da qualche parte intorno a .NET 4.5. Cambiamento abbastanza sensato.
Thread
costruttore. MA, questo solleva la domanda, perché hai bisogno di uno stack più grande?