Vous regardez le gars qui a fait ce choix. David Cutler et son équipe ont sélectionné un mégaoctet comme taille de pile par défaut. Rien à voir avec .NET ou C #, cela a été cloué lors de la création de Windows NT. Un mégaoctet est ce qu'il choisit lorsque l'en-tête EXE d'un programme ou l'appel winapi CreateThread () ne spécifie pas explicitement la taille de la pile. Ce qui est la manière normale, presque tous les programmeurs laissent au système d'exploitation le soin de choisir la taille.
Ce choix est probablement antérieur à la conception de Windows NT, l'histoire est bien trop trouble à ce sujet. Ce serait bien si Cutler écrivait un livre à ce sujet, mais il n'a jamais été écrivain. Il a été extrêmement influent sur le fonctionnement des ordinateurs. Sa première conception de système d'exploitation était RSX-11M, un système d'exploitation 16 bits pour les ordinateurs DEC (Digital Equipment Corporation). Il a fortement influencé le CP / M de Gary Kildall, le premier système d'exploitation décent pour les microprocesseurs 8 bits. Ce qui a fortement influencé MS-DOS.
Sa conception suivante était VMS, un système d'exploitation pour processeurs 32 bits avec prise en charge de la mémoire virtuelle. Connait un grand succès. Son prochain a été annulé par DEC au moment où la société a commencé à se désintégrer, ne pouvant pas rivaliser avec du matériel informatique bon marché. Cue Microsoft, ils lui ont fait une offre qu'il ne pouvait pas refuser. Beaucoup de ses collègues l'ont également rejoint. Ils ont travaillé sur VMS v2, mieux connu sous le nom de Windows NT. DEC s'est énervé à ce sujet, l'argent a changé de mains pour le régler. Je ne sais pas si VMS a déjà choisi un mégaoctet, je ne connais que RSX-11 assez bien. Ce n'est pas improbable.
Assez d'histoire. Un mégaoctet, c'est beaucoup , un vrai thread consomme rarement plus de quelques poignées de kilo-octets. Donc, un mégaoctet est en fait plutôt un gaspillage. C'est cependant le genre de gaspillage que vous pouvez vous permettre sur un système d'exploitation de mémoire virtuelle paginée à la demande, ce mégaoctet n'est que de la mémoire virtuelle . Juste des nombres pour le processeur, un pour chaque 4096 octets. Vous n'utilisez jamais réellement la mémoire physique, la RAM de la machine, jusqu'à ce que vous l'adressiez réellement.
Il est extrêmement excessif dans un programme .NET car la taille d'un mégaoctet a été initialement choisie pour accueillir les programmes natifs. Qui ont tendance à créer de grands cadres de pile, stockant également des chaînes et des tampons (tableaux) sur la pile. Tristement célèbre pour être un vecteur d'attaque de malware, un débordement de tampon peut manipuler le programme avec des données. Ce n'est pas la façon dont les programmes .NET fonctionnent, les chaînes et les tableaux sont alloués sur le tas GC et l'indexation est vérifiée. La seule façon d'allouer de l'espace sur la pile avec C # est d' utiliser le mot clé unsafe stackalloc .
La seule utilisation non triviale de la pile dans .NET est la gigue. Il utilise la pile de votre thread pour compiler juste à temps MSIL en code machine. Je n'ai jamais vu ni vérifié l'espace dont il a besoin, cela dépend plutôt de la nature du code et si l'optimiseur est activé ou non, mais quelques dizaines de kilo-octets sont une estimation approximative. Ce qui est autrement ainsi que ce site Web tire son nom, un débordement de pile dans un programme .NET est assez fatal. Il n'y a pas assez d'espace disponible (moins de 3 kilo-octets) pour toujours JIT de manière fiable tout code qui tente d'attraper l'exception. Kaboom au bureau est la seule option.
Dernier point mais non le moindre, un programme .NET fait quelque chose d'assez improductif avec la pile. Le CLR validera la pile d'un thread. C'est un mot coûteux qui signifie qu'il ne réserve pas seulement la taille de la pile, il s'assure également que l'espace est réservé dans le fichier d'échange du système d'exploitation afin que la pile puisse toujours être échangée si nécessaire. Le fait de ne pas s'engager est une erreur fatale et met fin à un programme sans condition. Cela ne se produit que sur une machine avec très peu de RAM qui exécute trop de processus, une telle machine se sera transformée en mélasse avant que les programmes ne commencent à mourir. Un problème possible il y a plus de 15 ans, pas aujourd'hui. Les programmeurs qui règlent leur programme pour agir comme une voiture de course F1 utilisent l' <disableCommitThreadStack>
élément dans leur fichier .config.
Fwiw, Cutler n'a pas arrêté de concevoir des systèmes d'exploitation. Cette photo a été prise alors qu'il travaillait sur Azure.
Mise à jour, j'ai remarqué que .NET ne valide plus la pile. Je ne sais pas exactement quand ni pourquoi cela s'est produit, cela fait trop longtemps que j'ai vérifié. Je suppose que ce changement de conception s'est produit quelque part autour de .NET 4.5. Changement assez sensible.
Thread
constructeur. MAIS, cela soulève la question, pourquoi avez-vous besoin d'une pile plus grande?