Wenn Sie eine Funktion aufrufen, wird auf dem Stack ein neuer "Namespace" zugewiesen. Auf diese Weise können Funktionen lokale Variablen haben. Wenn Funktionen Funktionen aufrufen, die wiederum Funktionen aufrufen, weisen wir immer mehr Platz auf dem Stack zu, um diese tiefe Hierarchie von Namespaces aufrechtzuerhalten.
Um Programme zu begrenzen, die große Mengen an Stack-Speicherplatz verbrauchen, wird normalerweise eine Begrenzung über ulimit -s
eingerichtet . Wenn wir dieses Limit über ulimit -s unlimited
aufheben , werden unsere Programme in der Lage sein, RAM für ihren ständig wachsenden Stapel zu verschlingen, bis dem System schließlich der Speicher vollständig ausgeht.
int eat_stack_space(void) { return eat_stack_space(); }
// If we compile this with no optimization and run it, our computer could crash.
Normalerweise ist die Verwendung einer Tonne Stack-Speicherplatz versehentlich oder ein Symptom einer sehr tiefen Rekursion, die sich wahrscheinlich nicht so sehr auf den Stack verlassen sollte. Daher das Stack-Limit.
Die Auswirkungen auf die Leistung sind gering, aber vorhanden. Mit time
Befehl habe ich festgestellt, dass die Beseitigung des Stack-Limits die Leistung um einige Sekundenbruchteile erhöht (zumindest auf 64-Bit-Ubuntu).
ulimit -s unlimited
lässt den Stack unbegrenzt wachsen.
Dies kann verhindern, dass Ihr Programm abstürzt, wenn Sie Programme durch Rekursion schreiben, insbesondere wenn Ihre Programme nicht endrekursiv sind (Compiler können diese "optimieren") und die Rekursionstiefe groß ist.
Stapelgröße kann tatsächlich unbegrenzt sein. _STK_LIM
ist die Standardeinstellung , _STK_LIM_MAX
ist etwas, das je nach Architektur unterschiedlich ist, wie aus include/asm-generic/resource.h
ersichtlich ist :
/*
* RLIMIT_STACK default maximum - some architectures override it:
*/
#ifndef _STK_LIM_MAX
# define _STK_LIM_MAX RLIM_INFINITY
#endif
Wie aus diesem Beispiel ersichtlich ist, ist der generische Wert unendlich, wobei RLIM_INFINITY
ist wiederum im allgemeinen Fall definiert als:
/*
* SuS says limits have to be unsigned.
* Which makes a ton more sense anyway.
*
* Some architectures override this (for compatibility reasons):
*/
#ifndef RLIM_INFINITY
# define RLIM_INFINITY (~0UL)
#endif
Ich denke also, die eigentliche Antwort lautet:Die Stapelgröße KANN durch eine Architektur begrenzt sein, dann bedeutet unbegrenzter Stapel-Trace, was auch immer _STK_LIM_MAX
ist definiert ist, und falls es unendlich ist - es ist unendlich. Einzelheiten dazu, was es bedeutet, es auf unendlich zu setzen, und welche Auswirkungen es haben könnte, finden Sie in der anderen Antwort, es ist viel besser als meine.