Estás mirando al tipo que tomó esa decisión. David Cutler y su equipo seleccionaron un megabyte como tamaño de pila predeterminado. Nada que ver con .NET o C #, esto se concretó cuando crearon Windows NT. Un megabyte es lo que elige cuando el encabezado EXE de un programa o la llamada de winapi CreateThread () no especifica explícitamente el tamaño de la pila. Que es la forma normal, casi cualquier programador deja que el sistema operativo elija el tamaño.
Esa elección probablemente sea anterior al diseño de Windows NT, la historia es demasiado turbia al respecto. Sería bueno que Cutler escribiera un libro al respecto, pero nunca ha sido escritor. Ha tenido una influencia extraordinaria en la forma en que funcionan las computadoras. Su primer diseño de sistema operativo fue RSX-11M, un sistema operativo de 16 bits para computadoras DEC (Digital Equipment Corporation). Influyó mucho en el CP / M de Gary Kildall, el primer sistema operativo decente para microprocesadores de 8 bits. Lo que influyó mucho en MS-DOS.
Su siguiente diseño fue VMS, un sistema operativo para procesadores de 32 bits con soporte de memoria virtual. Muy exitoso. El siguiente fue cancelado por DEC cuando la compañía comenzó a desintegrarse, sin poder competir con hardware de PC barato. Cue Microsoft, le hicieron una oferta que no pudo rechazar. Muchos de sus compañeros de trabajo también se unieron. Trabajaron en VMS v2, más conocido como Windows NT. DEC se molestó por eso, el dinero cambió de manos para liquidarlo. Si VMS ya eligió un megabyte es algo que no sé, solo conozco RSX-11 lo suficientemente bien. No es improbable.
Suficiente historia. Un megabyte es mucho , un hilo real rara vez consume más de un par de puñados de kilobytes. Entonces, un megabyte es en realidad un desperdicio. Sin embargo, es el tipo de desperdicio que puede permitirse en un sistema operativo de memoria virtual paginada a demanda, ese megabyte es solo memoria virtual . Solo números para el procesador, uno por cada 4096 bytes. En realidad, nunca usa la memoria física, la RAM en la máquina, hasta que realmente la dirige.
Es más excesivo en un programa .NET porque el tamaño de un megabyte se eligió originalmente para adaptarse a los programas nativos. Que tienden a crear grandes marcos de pila, almacenando cadenas y búferes (matrices) en la pila también. Infame por ser un vector de ataque de malware, un desbordamiento de búfer puede manipular el programa con datos. No es la forma en que funcionan los programas .NET, las cadenas y las matrices se asignan en el montón de GC y se comprueba la indexación. La única forma de asignar espacio en la pila con C # es con la palabra clave unsafe stackalloc .
El único uso no trivial de la pila en .NET es el jitter. Utiliza la pila de su hilo para compilar MSIL en código de máquina justo a tiempo. Nunca he visto ni comprobado cuánto espacio requiere, más bien depende de la naturaleza del código y de si el optimizador está habilitado o no, pero un par de decenas de kilobytes es una suposición aproximada. Que de otra manera es como este sitio web obtuvo su nombre, un desbordamiento de pila en un programa .NET es bastante fatal. No queda suficiente espacio (menos de 3 kilobytes) para seguir JIT de manera confiable con cualquier código que intente detectar la excepción. Kaboom al escritorio es la única opción.
Por último, pero no menos importante, un programa .NET hace algo bastante improductivo con la pila. El CLR confirmará la pila de un hilo. Esa es una palabra cara que significa que no solo reserva el tamaño de la pila, sino que también se asegura de que se reserve espacio en el archivo de paginación del sistema operativo para que la pila siempre pueda intercambiarse cuando sea necesario. No confirmar es un error fatal y termina un programa incondicionalmente. Eso solo sucede en una máquina con muy poca RAM que ejecuta demasiados procesos, tal máquina se habrá convertido en melaza antes de que los programas comiencen a morir. Un posible problema hace más de 15 años, no hoy. Los programadores que ajustan su programa para que actúe como un coche de carreras de F1 utilizan el <disableCommitThreadStack>
elemento en su archivo .config.
Fwiw, Cutler no dejó de diseñar sistemas operativos. Esa foto se hizo mientras trabajaba en Azure.
Actualización, noté que .NET ya no confirma la pila. No estoy seguro de cuándo o por qué sucedió esto, ha pasado demasiado tiempo desde que lo comprobé. Supongo que este cambio de diseño ocurrió en algún lugar alrededor de .NET 4.5. Cambio bastante sensato.
Thread
constructor. PERO, esto plantea la pregunta, ¿por qué necesita una pila más grande?