Warum ist unter modernen Linux die Standardstapelgröße so groß - 8 MB (bei einigen Distributionen sogar 10)?

10

Unter OSX sind es beispielsweise sogar weniger als 512 KB.

Gibt es eine empfohlene Größe, wenn man bedenkt, dass die App keine Rekursion verwendet und nicht viele Stapelvariablen zuweist ?
Ich weiß, dass die Frage zu weit gefasst ist und stark von der Verwendung abhängt, wollte sie aber trotzdem stellen, da ich mich gefragt habe, ob hinter dieser riesigen Zahl ein versteckter / interner / systembedingter Grund steckt.


Ich habe mich gefragt, ob ich beabsichtige, die Stapelgröße in meiner App auf 512 KiB zu ändern - dies klingt immer noch nach einer großen Zahl, ist aber viel kleiner als 8 MB - und wird zu einem deutlich verringerten virtuellen Speicher des Prozesses führen, wie ich habe viele Threads (I / O).

Ich weiß auch, dass dies nicht wirklich weh tut, was hier gut erklärt wird : Standardstapelgröße für Pthreads

Kiril Kirov
quelle
Verwenden Sie eine 32-Bit-CPU? X86_64-CPUs bieten einen virtuellen Adressraum von bis zu 128 Terabyte (im Benutzerraum), was für viele 8-MB-Stapel ausreichen sollte.
Johan Myréen
@ JohanMyréen - nein, x64 ist es. Es ist keine große Sache, ich habe mich nur gefragt, es gibt keinen wirklichen Grund, dies zu tun (im Moment).
Kiril Kirov
In 2019 und 8 MiB ist viel Speicher? Das glaube ich nicht. Mit einer großen Standardstapelgröße ist es sehr einfach, Programme mit Rekursion zu schreiben. Ich war sehr überrascht zu wissen, dass die Standardstapelgröße unter Windows nur 1 MB beträgt!
Oldherl

Antworten:

15

Wie andere gesagt haben und wie in dem Link erwähnt, den Sie in Ihrer Frage angeben, schadet ein 8-MB-Stack nichts (abgesehen vom Verbrauch von Adressraum - auf einem 64-Bit-System, das keine Rolle spielt).

Linux verwendet seit sehr langer Zeit 8MiB-Stacks. Die Änderung wurde im Juli 1995 in Version 1.3.7 des Kernels eingeführt. Damals wurde sie als Einführung eines Limits vorgestellt, zuvor gab es kein Limit:

Begrenzen Sie den Stack auf einen vernünftigen Standard: root kann dieses Limit bei Bedarf jederzeit erhöhen. 8 MB scheinen vernünftig.

Unter Linux wirkt sich das Stapellimit auch auf die Größe der Programmargumente und der Umgebung aus, die auf ein Viertel des Stapellimits begrenzt sind . Der Kernel erzwingt mindestens 32 Seiten für die Argumente und die Umgebung.

Wenn für Threads das Stack-Limit ( RLIMIT_STACK) unbegrenzt ist, werden pthread_createfür die Stacks neuer Threads eigene Limits angewendet - und auf den meisten Architekturen sind dies weniger als 8 MB.

Stephen Kitt
quelle
1
Wow interessant. Ich dachte, das wurde kürzlich eingeführt. Ich habe ungefähr 200 Threads (das ist ein weiteres langes Thema, also ignorieren wir es für den Moment) und topzeige es in beängstigenden VIRT-Ergebnissen. Wenn Sie etwas tiefer graben, wird der größte Teil dieses virtuellen Adressraums aus den Arenen pro Thread (Speicher) und nicht aus der Stapelgröße entnommen, sodass durch Verringern der Stapelgröße der virtuelle Speicher nicht drastisch reduziert wird. Ich war nur neugierig, warum 8MiB und warum so viel.
Kiril Kirov
Die "8 MB" bedeuten nur, dass der Stapel jedes Threads auf 8 MB wachsen kann , wenn der Thread sich für die Verwendung entscheidet. Der physische Speicher wird jedoch erst zugewiesen, wenn der Speicher tatsächlich verwendet wird. Wenn Ihre 200 Threads jeweils 512 KB verwenden, verwenden Sie 100 MB physischen RAM, nicht 1,6 GB.
Guntram Blohm unterstützt Monica
Wenn Sie nicht tauschen, erhalten Sie in der Spalte RES topeine viel bessere Antwort auf die Frage, welchen Speicher dieser Prozess tatsächlich verwendet, als in VIRT.
Kbolino
1
@Guntram das OP ist sich dessen bewusst, siehe den Link in der Frage.
Stephen Kitt
1

8 MB ist die virtuelle Größe des Stapels. Ein Seitenfehler tritt auf, wenn Ihre Anwendung versucht, mehr Stapel zu verwenden, als derzeit physisch zugewiesen ist. Der Seitenfehler-Handler des Kernels weist dann eine physische Seite zu und Ihre Anwendung wird fortgesetzt.

Eine vollständige Erklärung finden Sie unter /unix//a/280865/21212 .

Das Reduzieren der Stapelgröße sollte daher keine Auswirkungen auf die Reduzierung der physischen Speichernutzung Ihrer Anwendung haben.

Colin 't Hart
quelle
1
Ich habe diese Antwort bereits in meiner Frage verlinkt. Ich habe auch geschrieben, dass ich mir dessen bewusst bin, aber das beantwortet die Frage nicht wirklich. Trotzdem danke
Kiril Kirov
Ich denke, Sie müssen die Prämissen der Frage noch einmal überdenken, und diese (Nicht-) Antwort zeigt, warum. Virtueller Speicher ist kein realer Speicher. Die Stapelgröße kann 800 MB betragen und hat keinen Einfluss auf die tatsächliche Speichernutzung, es sei denn, Ihre Anwendung hat Stapelrahmen im Wert von mehr als 8 MB erstellt.
Kbolino