Kürzlich habe ich das Limit eines Stacks auf drei Geräten mit unterschiedlichen Betriebssystemen getestet (mit Limit meine ich die maximale Anzahl von Levels, die der Stack haben kann), und ich habe festgestellt, dass es mir jedes Mal, wenn ich 2 ^ 16 Levels treffe, gibt Überlauffehler, und wenn ich 2 ^ 16-1 setze, funktioniert es richtig.
Meine Frage ist also - ist das wahr? Hat der Stack per Definition das maximale Limit 2 ^ 16-1 oder hängt es vom Betriebssystem ab?
here i mean by limit the maximum number of levels that can the stack have
Was ist ein Level?Antworten:
Es ist stark betriebssystemspezifisch (und rechnerspezifisch) und unter einigen Betriebssystemen haben Sie einige Möglichkeiten, das Limit zu konfigurieren (und sogar zu erhöhen). Es ist sogar compilerspezifisch (oder spezifisch für Ihre Programmiersprachenimplementierung), da einige Compiler (einschließlich des aktuellen GCC für eine begrenzte Art von C-Code) einige Tail-Aufrufe optimieren können .
(Einige Programmiersprachen-Spezifikationen erfordern Tail-Call-Optimierungen, z. B. R5RS. )
Ich bin mir nicht sicher, ob Ihre Frage Sinn macht (und schon gar nicht Ihr 2 16- Limit). Auf meinem Linux-Desktop (Debian / Sid / x86-64, Linux 4.9-Kernel, 32 GB RAM, Intel i5-4690S) habe ich möglicherweise einen Aufrufstapel von bis zu 8 Megabyte (und ich könnte dieses Limit erhöhen, wenn ich es wirklich wollte ).
Multithreading und ASLR machen Ihre Frage viel komplexer . Siehe z. B. pthread_attr_setstack (3) . Lesen Sie auch über Split-Stacks (häufig von Go- Implementierungen verwendet) und über den Continuation-Passing-Stil . Siehe auch diese Antwort.
Für das, was es wert ist, habe ich gerade den folgenden C99 (und auch C11) Code ausprobiert:
und ich konnte dieses
recur
Programm (kompiliert mit GCC 6 asgcc -Wall -O recur.c -o recur
) ausführenrecur 161000
(so weit über Ihrem 2 16- Limit). Damit hatrecur 256000
es auch geklappt. Damitrecur 456000
stürzte es ab (mit einem Stapelüberlauf für Levelx=272057
). Ich habe nicht die Geduld für andere Tests. Versuchen Sie das auf Ihrem Computer. Vergessen Sie nicht, nach Optimierungen zu fragen.Als Faustregel (für Desktops, Laptops, Tablets) gilt möglicherweise, dass Ihr Anrufstapel unter einem Megabyte liegt.
Wenn ich auch
-fstack-usage
an übergebe , erhaltegcc
ich die folgenderecur.su
Datei (Zahlen sind in Bytes, was mit meiner 8-MB-Stapelbegrenzungsintuition übereinstimmt; vergessen Sie nicht den Aufrufrahmenmain
und vor allem das anfängliche Stapellayout, das der Kernel beim Ausführen installiert hat (2) ) ..., für crt0 ):PS. Mein Arduino hat einen Atmega328 mit nur 2 KB RAM, kann also sicher nicht so viel wiederholen. Ich denke, auf Arduinos sind höchstens ein paar Hundert Stack-Frames praktisch möglich.
quelle
Die Stapelgröße für den Hauptthread eines Windows-Prozesses wird vom Linker festgelegt. Der Standardwert ist 1 MB, kann jedoch mit dem Schalter / STACK eingestellt werden. Später erstellte Threads können den Parameter dwStackSize der Funktion CreateThread verwenden.
Wenn Sie also verschiedene Windows-Betriebssysteme testen, haben alle seit mindestens NT4.0 dieselbe Standardstapelgröße.
quelle