Zusamenfassend
Ein Stapel wird für die statische Speicherzuweisung und ein Heap für die dynamische Speicherzuweisung verwendet, die beide im RAM des Computers gespeichert sind.
Im Detail
Der Stapel
Der Stack ist eine "LIFO" -Datenstruktur (last in, first out), die von der CPU sehr genau verwaltet und optimiert wird. Jedes Mal, wenn eine Funktion eine neue Variable deklariert, wird sie auf den Stapel "geschoben". Jedes Mal, wenn eine Funktion beendet wird, werden alle von dieser Funktion auf den Stapel geschobenen Variablen freigegeben (dh sie werden gelöscht). Sobald eine Stapelvariable freigegeben ist, wird dieser Speicherbereich für andere Stapelvariablen verfügbar.
Der Vorteil der Verwendung des Stapels zum Speichern von Variablen besteht darin, dass der Speicher für Sie verwaltet wird. Sie müssen den Speicher nicht manuell zuweisen oder freigeben, wenn Sie ihn nicht mehr benötigen. Da die CPU den Stapelspeicher so effizient organisiert, ist das Lesen und Schreiben von Stapelvariablen sehr schnell.
Mehr finden Sie hier .
Der Haufen
Der Heap ist ein Bereich des Arbeitsspeichers Ihres Computers, der nicht automatisch für Sie verwaltet wird und von der CPU nicht so streng verwaltet wird. Es ist ein frei schwebender Speicherbereich (und größer). Um Speicher auf dem Heap zuzuweisen, müssen Sie malloc () oder calloc () verwenden, die integrierte C-Funktionen sind. Sobald Sie Speicher auf dem Heap zugewiesen haben, sind Sie dafür verantwortlich, free () zu verwenden, um die Zuweisung dieses Speichers aufzuheben, sobald Sie ihn nicht mehr benötigen.
Wenn Sie dies nicht tun, weist Ihr Programm einen sogenannten Speicherverlust auf. Das heißt, der Speicher auf dem Heap wird weiterhin reserviert (und steht anderen Prozessen nicht zur Verfügung). Wie wir im Abschnitt zum Debuggen sehen werden, gibt es ein Tool namens Valgrind , mit dem Sie Speicherlecks erkennen können.
Im Gegensatz zum Stapel unterliegt der Heap keinen Größenbeschränkungen für die variable Größe (abgesehen von den offensichtlichen physischen Einschränkungen Ihres Computers). Der Heap-Speicher ist etwas langsamer zum Lesen und Schreiben, da Zeiger verwendet werden müssen, um auf den Speicher des Heaps zuzugreifen. Wir werden in Kürze über Hinweise sprechen.
Im Gegensatz zum Stapel können Variablen, die auf dem Heap erstellt wurden, von jeder Funktion an einer beliebigen Stelle in Ihrem Programm aufgerufen werden. Heap-Variablen sind im Wesentlichen global.
Mehr finden Sie hier .
Auf dem Stapel zugewiesene Variablen werden direkt im Speicher gespeichert, und der Zugriff auf diesen Speicher ist sehr schnell, und seine Zuordnung wird beim Kompilieren des Programms behandelt. Wenn eine Funktion oder eine Methode eine andere Funktion aufruft, die wiederum eine andere Funktion usw. aufruft, bleibt die Ausführung all dieser Funktionen ausgesetzt, bis die allerletzte Funktion ihren Wert zurückgibt. Der Stapel wird immer in einer LIFO-Reihenfolge reserviert. Der zuletzt reservierte Block ist immer der nächste freizugebende Block. Dies macht es wirklich einfach, den Stapel im Auge zu behalten. Das Lösen eines Blocks vom Stapel ist nichts anderes als das Anpassen eines Zeigers.
Auf dem Heap zugewiesenen Variablen wird zur Laufzeit der Speicher zugewiesen, und der Zugriff auf diesen Speicher ist etwas langsamer, die Größe des Heapspeichers ist jedoch nur durch die Größe des virtuellen Speichers begrenzt. Elemente des Heaps haben keine Abhängigkeiten voneinander und können jederzeit nach dem Zufallsprinzip aufgerufen werden. Sie können einen Block jederzeit zuweisen und jederzeit freigeben. Dies macht es viel komplexer zu verfolgen, welche Teile des Heaps zu einem bestimmten Zeitpunkt zugewiesen oder frei sind.
Sie können den Stapel verwenden, wenn Sie genau wissen, wie viele Daten Sie vor der Kompilierungszeit zuweisen müssen, und er nicht zu groß ist. Sie können den Heap verwenden, wenn Sie nicht genau wissen, wie viele Daten Sie zur Laufzeit benötigen oder wenn Sie viele Daten zuweisen müssen.
In einer Situation mit mehreren Threads hat jeder Thread seinen eigenen, völlig unabhängigen Stapel, aber sie teilen sich den Heap. Der Stack ist threadspezifisch und der Heap ist anwendungsspezifisch. Der Stapel ist wichtig bei der Ausnahmebehandlung und Thread-Ausführung.
Jeder Thread erhält einen Stapel, während es normalerweise nur einen Heap für die Anwendung gibt (obwohl es nicht ungewöhnlich ist, mehrere Heaps für verschiedene Zuordnungstypen zu haben).
Wenn die Anwendung zur Laufzeit mehr Heap benötigt, kann sie Speicher aus dem freien Speicher zuweisen, und wenn der Stapel Speicher benötigt, kann sie Speicher aus dem freien Speicher zuweisen, der der Anwendung zugewiesen ist.
Noch mehr Details werden hier und hier gegeben .
Kommen Sie nun zu den Antworten Ihrer Frage .
Inwieweit werden sie vom Betriebssystem oder der Sprachlaufzeit gesteuert?
Das Betriebssystem weist den Stapel jedem Thread auf Systemebene zu, wenn der Thread erstellt wird. In der Regel wird das Betriebssystem von der Sprachlaufzeit aufgerufen, um den Heap für die Anwendung zuzuweisen.
Mehr finden Sie hier .
Was ist ihr Umfang?
Bereits oben angegeben.
"Sie können den Stapel verwenden, wenn Sie genau wissen, wie viele Daten Sie vor der Kompilierungszeit zuweisen müssen, und er nicht zu groß ist. Sie können den Heap verwenden, wenn Sie nicht genau wissen, wie viele Daten Sie zur Laufzeit benötigen oder wenn Sie müssen viele Daten zuweisen. "
Mehr finden Sie hier .
Was bestimmt die Größe jedes einzelnen von ihnen?
Die Größe des Stapels wird vom Betriebssystem festgelegt, wenn ein Thread erstellt wird. Die Größe des Heapspeichers wird beim Start der Anwendung festgelegt, kann jedoch bei Bedarf an Speicherplatz zunehmen (der Allokator fordert mehr Speicher vom Betriebssystem an).
Was macht einen schneller?
Die Stapelzuweisung ist viel schneller, da nur der Stapelzeiger bewegt wird. Wenn Sie Speicherpools verwenden, können Sie eine vergleichbare Leistung bei der Heap-Zuweisung erzielen. Dies ist jedoch mit einer geringfügig zusätzlichen Komplexität und eigenen Kopfschmerzen verbunden.
Außerdem ist Stack vs. Heap nicht nur eine Leistungsüberlegung. Außerdem erfahren Sie viel über die erwartete Lebensdauer von Objekten.
Details finden Sie hier .