PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wieviel Stack hat man?


mekakic
2008-10-07, 10:51:23
Hallo,

ich frage mich gerade, wieviel Stack ein Programm haben kann? Visual Studio soll per default 1MiB Stack erlauben (und mittels /Fsize anpassbar). Ist die Stackgröße nur eine Sache des Compilers und kann man das auf beliebige Werte drehen, solange genug Speicher im System vorhanden ist? Oder gibt es da Grenzen die durch das Betriebssystem oder die Hardware gesetzt werden, was als Stack verwendet werden kann?

Wird der Stackspeicher am Anfang einmal am Stück genauso angelegt, wie man sich später selber Brocken aus dem Heap holen kann?

danke

Monger
2008-10-07, 11:48:20
Von welchem Stack genau reden wir hier?
Vom Methodenstack? Vom Objektstack der Runtime? Von einem Stack Objekt was man im Programm verwendet?

Der Methodenstack und der Objektstack sind meines Wissens einfach nur Parameter der Runtime die man auch ändern kann. Der Objektstack ist ja dazu da, um alle Objekte zu verwalten die gerade in der Runtime existieren, um sie dann z.B. aufzuräumen. Ist der von vorneherein zu groß angelegt, drückt das auf die Performance. Die Tiefe bei einem Methodenaufruf ist möglicherweise schlicht eine Limitierung des Compilers bzw. der Runtime.

Aber deine Frage ist wahrscheinlich, ob die CPU ein physikalisches Limit kennt?!?
Meines Wissens: außer dem Addressraum keinen. Natürlich verwendet die CPU intern irgendwelche Stacks um bestimmte Befehlscodes zu puffern, aber wann und wie die leergeräumt und möglicherweise verschoben werden - davon kriegst du als Anwender nichts mit. Solche Details sind Sache der CPU selbst, nichtmal des Compilers. Du schiebst einfach nur Befehl für Befehl nach, und da existiert wie gesagt meines Wissens keine Begrenzung. Wäre ja auch schlimm, wenn du mit so einem Überlauf die CPU freezen könntest! ;)

mekakic
2008-10-07, 12:48:13
Hmm, vielleicht bekomme ich das gerade durcheinander, aber ich dachte immer Methodenstack und Objektstack wären das gleiche bzw. mir ist nicht klar, wieso es beides geben kann.

Mein Bild sah bisher so aus: es geht etwas vereinfacht in der main() los und die ersten angelegten Variablen landen in der Reihenfolge auf dem Stack. Wenn der erste Funktionsaufruf kommt, werden dann Parameter und Rücksprungadresse darauf abgelegt und zur Funktion gesprungen, dann kommen wieder die lokalen Variablen der entsprechenden Funktion und allen weiteren Subcalls, je nachdem wie sie ablaufen. Wenn man das Ende eines Stacks Kontexts erreicht, werden die Variablen durch den Stack wieder Rückwärts zerstört bzw. der Kontext wandert nach unten. Dann kommt man zur Rücksprungadresse, springt wieder in den alten Kontext. Dann steht der Füllstandsanzeiger wieder auf dem Level, wo er vor dem Funktionsaufruf war und es geht weiter. Der Stack ist dann in der Größe begrenzt, in der Form wie die Applikation kompiliert wurde oder -- das war meine Frage -- auch durch irgendwelche Grenzen in OS/Architektur.

Ist dieses Bild grundsätzlich falsch und wie würde man dann vom Ablauf her Objekt und Methodenstacks trennen? Das ist mir irgendwie nicht klar.

Monger
2008-10-07, 12:57:01
Das was du beschreibst, ist der Methodenstack, und soweit ich das sehe völlig korrekt.

Und ich muss mich gleich mal korrigieren: das was ich meinte war der Objekt Heap, nicht Stack. Sorry, kleiner Denkfehler. Einen Objekt Stack gibt es nicht.

mekakic
2008-11-04, 15:17:44
Kann man sich eigentlich die Größe des aktuell belegten Stackspeichers zur Laufzeit irgendwie anzeigen lassen?

Wie ist das bei mehreren Threads? Hat jeder Thread genau wie eine Applikation einen maximalen Stack? Kann mir gerade nur schwer vorstellen, wie unterschiedliche Threads auf einem Applikationsstack unterwegs sind.

Trap
2008-11-04, 15:28:49
Es ist nicht sonderlich schwer an die Belegung des Stackspeichers zu kommen, auch ohne spezielle Funktion dafür, in der main() eine lokale Variable erzeugen, die Adresse global speichern. Wenn man die Belegung wissen will: lokale Variable erzeugen, Abstand der Adresse der neuen lokalen Variable zur global gespeicherten Adresse ist die genutzte Stackgröße.

Jeder Thread hat einen eigenen Stack.

The_Invisible
2008-11-04, 17:02:52
Es ist nicht sonderlich schwer an die Belegung des Stackspeichers zu kommen, auch ohne spezielle Funktion dafür, in der main() eine lokale Variable erzeugen, die Adresse global speichern. Wenn man die Belegung wissen will: lokale Variable erzeugen, Abstand der Adresse der neuen lokalen Variable zur global gespeicherten Adresse ist die genutzte Stackgröße.

Jeder Thread hat einen eigenen Stack.

und da entsehen keine lücken?

bzw kann man dann die stackgröße mit den abstand zwischen erster lokaler variable und erster "heap" variable (malloc) feststellen?

mfg

Gast
2008-11-04, 17:36:35
Das was du beschreibst, ist der Methodenstack, und soweit ich das sehe völlig korrekt.
Also den Begriff "Methodenstack" hab ich in diesem Zusammenhang noch nie gehört (was natürlich nicht heißen soll, das es die Bezeichnung nicht geben kann ;) ). "Call Stack" (oder einfach nur "Stack") ist glaube ich üblicher.

Trap
2008-11-04, 18:12:46
und da entsehen keine lücken?
Sagt dir "Stack" etwas? :tongue:

Heap und Stack liegen nicht unbedingt nebeneinander und der Heap wird nicht unbedingt der Reihe nach benutzt.

mekakic
2008-11-06, 12:57:26
Es ist nicht sonderlich schwer an die Belegung des Stackspeichers zu kommen, auch ohne spezielle Funktion dafür, in der main() eine lokale Variable erzeugen, die Adresse global speichern. Wenn man die Belegung wissen will: lokale Variable erzeugen, Abstand der Adresse der neuen lokalen Variable zur global gespeicherten Adresse ist die genutzte Stackgröße.

Jeder Thread hat einen eigenen Stack.Das hat perfekt funktioniert - Danke!