Sie sehen den Mann, der diese Wahl getroffen hat. David Cutler und sein Team haben ein Megabyte als Standardstapelgröße ausgewählt. Nichts mit .NET oder C # zu tun, dies wurde beim Erstellen von Windows NT festgenagelt. Ein Megabyte wird ausgewählt, wenn der EXE-Header eines Programms oder der Winapi-Aufruf CreateThread () die Stapelgröße nicht explizit angibt. Das ist der normale Weg, fast jeder Programmierer überlässt es dem Betriebssystem, die Größe auszuwählen.
Diese Wahl datiert wahrscheinlich vor dem Windows NT-Design, die Geschichte ist diesbezüglich viel zu trübe. Wäre schön, wenn Cutler ein Buch darüber schreiben würde, aber er war nie Schriftsteller. Er hat die Arbeitsweise von Computern außerordentlich beeinflusst. Sein erstes Betriebssystem war RSX-11M, ein 16-Bit-Betriebssystem für DEC-Computer (Digital Equipment Corporation). Es hat Gary Kildalls CP / M, das erste anständige Betriebssystem für 8-Bit-Mikroprozessoren, stark beeinflusst. Was MS-DOS stark beeinflusst hat.
Sein nächstes Design war VMS, ein Betriebssystem für 32-Bit-Prozessoren mit Unterstützung für virtuellen Speicher. Sehr erfolgreich. Sein nächstes wurde von DEC abgesagt, als das Unternehmen anfing, sich aufzulösen, da es nicht in der Lage war, mit billiger PC-Hardware zu konkurrieren. Cue Microsoft, sie machten ihm ein Angebot, das er nicht ablehnen konnte. Viele seiner Mitarbeiter schlossen sich ebenfalls an. Sie arbeiteten an VMS v2, besser bekannt als Windows NT. DEC war darüber verärgert, Geld wechselte den Besitzer, um es zu regeln. Ob VMS bereits ein Megabyte ausgewählt hat, weiß ich nicht, ich kenne RSX-11 nur gut genug. Das ist nicht unwahrscheinlich.
Genug Geschichte. Ein Megabyte ist viel , ein echter Thread verbraucht selten mehr als ein paar Handvoll Kilobyte. Ein Megabyte ist also eigentlich ziemlich verschwenderisch. Es ist jedoch die Art von Verschwendung, die Sie sich bei einem bedarfsgesteuerten Betriebssystem für virtuellen Speicher leisten können, dass Megabyte nur virtueller Speicher ist . Nur Zahlen an den Prozessor, jeweils eine pro 4096 Bytes. Sie verwenden niemals den physischen Speicher, den RAM in der Maschine, bis Sie ihn tatsächlich ansprechen.
In einem .NET-Programm ist dies besonders übertrieben, da die Größe von einem Megabyte ursprünglich für native Programme ausgewählt wurde. Diese neigen dazu, große Stapelrahmen zu erstellen und Zeichenfolgen und Puffer (Arrays) ebenfalls auf dem Stapel zu speichern. Ein Pufferüberlauf, der als Malware-Angriffsvektor berüchtigt ist, kann das Programm mit Daten manipulieren. Nicht die Art und Weise, wie .NET-Programme funktionieren, Zeichenfolgen und Arrays werden auf dem GC-Heap zugewiesen und die Indizierung wird überprüft. Die einzige Möglichkeit, mit C # Speicherplatz auf dem Stapel zuzuweisen, ist das Schlüsselwort unsicheres stackalloc .
Die einzige nicht triviale Verwendung des Stacks in .NET erfolgt durch den Jitter. Es verwendet den Stapel Ihres Threads, um MSIL just-in-time zu Maschinencode zu kompilieren. Ich habe noch nie gesehen oder überprüft, wie viel Speicherplatz benötigt wird. Es hängt vielmehr von der Art des Codes ab und davon, ob der Optimierer aktiviert ist oder nicht, aber ein paar zehn Kilobyte sind eine grobe Vermutung. Ansonsten hat diese Website ihren Namen erhalten. Ein Stapelüberlauf in einem .NET-Programm ist ziemlich fatal. Es ist nicht mehr genügend Speicherplatz vorhanden (weniger als 3 Kilobyte), um noch zuverlässig Code zu JITEN, der versucht, die Ausnahme abzufangen. Kaboom to Desktop ist die einzige Option.
Last but not least macht ein .NET-Programm etwas ziemlich Unproduktives mit dem Stack. Die CLR schreibt den Stapel eines Threads fest. Das ist ein teures Wort, das bedeutet, dass nicht nur die Größe des Stapels reserviert wird, sondern auch sichergestellt wird, dass Speicherplatz in der Auslagerungsdatei des Betriebssystems reserviert ist, sodass der Stapel bei Bedarf jederzeit ausgetauscht werden kann. Das Nicht-Festschreiben ist ein schwerwiegender Fehler und beendet ein Programm bedingungslos. Dies geschieht nur auf einem Computer mit sehr wenig RAM, auf dem viel zu viele Prozesse ausgeführt werden. Ein solcher Computer hat sich in Melasse verwandelt, bevor Programme zu sterben beginnen. Ein mögliches Problem vor mehr als 15 Jahren, nicht heute. Programmierer, die ihr Programm so <disableCommitThreadStack>
einstellen, dass es sich wie ein F1-Rennwagen verhält , verwenden das Element in ihrer .config-Datei.
Fwiw, Cutler hat nicht aufgehört, Betriebssysteme zu entwerfen. Dieses Foto wurde gemacht, während er an Azure arbeitete.
Update, ich habe festgestellt, dass .NET den Stack nicht mehr festschreibt. Ich bin mir nicht ganz sicher, wann oder warum dies passiert ist. Es ist zu lange her, seit ich es überprüft habe. Ich vermute, dass diese Designänderung irgendwo um .NET 4.5 herum stattgefunden hat. Ziemlich vernünftige Veränderung.
Thread
Konstruktors verwenden. ABER das wirft die Frage auf, warum Sie einen größeren Stapel benötigen.