logo

Stack vs. Heap-Speicherzuordnung

Speicher in einem C/C++/Java-Programm kann entweder auf einem Stapel oder einem Heap zugewiesen werden.
Voraussetzung: Speicherlayout des C-Programms .


Stapelzuteilung: Die Zuweisung erfolgt für zusammenhängende Speicherblöcke. Wir nennen es eine Stapelspeicherzuweisung, da die Zuweisung im Funktionsaufrufstapel erfolgt. Die Größe des zuzuordnenden Speichers ist dem Compiler bekannt und bei jedem Aufruf einer Funktion wird ihren Variablen Speicher auf dem Stapel zugewiesen. Und wann immer der Funktionsaufruf beendet ist, wird der Speicher für die Variablen freigegeben. Dies alles geschieht mithilfe einiger vordefinierter Routinen im Compiler. Ein Programmierer muss sich nicht um die Speicherzuweisung und -freigabe von Stack-Variablen kümmern. Diese Art der Speicherzuweisung wird auch als temporäre Speicherzuweisung bezeichnet, da alle zu dieser Methode gehörenden Daten automatisch aus dem Stapel gelöscht werden, sobald die Methode ihre Ausführung beendet. Dies bedeutet, dass auf jeden im Stapelspeicherschema gespeicherten Wert zugegriffen werden kann, solange die Methode ihre Ausführung noch nicht abgeschlossen hat und sich derzeit im Ausführungszustand befindet.



ABS-C-Code

Wichtige Punkte:

  • Es handelt sich um ein temporäres Speicherzuweisungsschema, bei dem auf die Datenelemente nur dann zugegriffen werden kann, wenn die Methode (), die sie enthielt, gerade ausgeführt wird.
  • Der Speicher wird automatisch zugewiesen oder freigegeben, sobald die entsprechende Methode ihre Ausführung abgeschlossen hat.
  • Wir erhalten den entsprechenden Fehler Java. lang. StackOverFlowError von JVM , Wenn der Stapelspeicher vollständig gefüllt ist.
  • Die Stapelspeicherzuweisung gilt im Vergleich zur Heapspeicherzuweisung als sicherer, da nur der Eigentümerthread auf die gespeicherten Daten zugreifen kann.
  • Die Speicherzuweisung und -freigabe ist im Vergleich zur Heap-Speicherzuweisung schneller.
  • Der Stapelspeicher verfügt im Vergleich zum Heap-Speicher über weniger Speicherplatz.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; }>


Heap-Zuordnung: Der Speicher wird während der Ausführung der von Programmierern geschriebenen Anweisungen zugewiesen. Beachten Sie, dass der Name Heap nichts mit dem zu tun hat Speicherleck kann im Programm passieren.



Die Heap-Speicherzuweisung ist weiter in drei Kategorien unterteilt: Diese drei Kategorien helfen uns, die Daten (Objekte) zu priorisieren, die im Heap-Speicher oder im gespeichert werden sollen Müllabfuhr .

Unterschied zwischen einem Löwen und einem Tiger
  • Junge Generation - Es ist der Teil des Speichers, in dem alle neuen Daten (Objekte) erstellt werden, um den Speicherplatz zuzuweisen. Wenn dieser Speicher vollständig gefüllt ist, werden die restlichen Daten in der Garbage Collection gespeichert.
  • Alte oder festsitzende Generation – Dies ist der Teil des Heap-Speichers, der die älteren Datenobjekte enthält, die nicht häufig oder überhaupt nicht verwendet werden.
  • Permanente Generation – Dies ist der Teil des Heap-Speichers, der die Metadaten der JVM für die Laufzeitklassen und Anwendungsmethoden enthält.

Wichtige Punkte:

  • Wir erhalten die entsprechende Fehlermeldung, wenn der Heap-Speicher vollständig voll ist. Java. lang.OutOfMemoryError von JVM.
  • Dieses Speicherzuweisungsschema unterscheidet sich von der Stapelplatzzuweisung, hier ist keine Funktion zur automatischen Aufhebung der Zuweisung vorgesehen. Wir müssen einen Garbage Collector verwenden, um die alten ungenutzten Objekte zu entfernen, um den Speicher effizient zu nutzen.
  • Die Verarbeitungszeit (Zugriffszeit) dieses Speichers ist im Vergleich zum Stapelspeicher recht langsam.
  • Heap-Speicher ist auch nicht so threadsicher wie Stack-Speicher, da die im Heap-Speicher gespeicherten Daten für alle Threads sichtbar sind.
  • Die Größe des Heap-Speichers ist im Vergleich zum Stack-Speicher deutlich größer.
  • Der Heap-Speicher ist zugänglich oder vorhanden, solange die gesamte Anwendung (oder das Java-Programm) ausgeführt wird.
CPP
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; }>

Gemischtes Beispiel für beide Arten der Speicherzuweisung Heap und Stack in Java:



C++
#include  using namespace std; int main() {  int a = 10; // stored in stack  int* p = new int(); // allocate memory in heap  *p = 10;  delete (p);  p = new int[4]; // array in heap allocation  delete[] p;  p = NULL; // free heap  return 0; }>
Java
class Emp {  int id;  String emp_name;  public Emp(int id, String emp_name) {  this.id = id;  this.emp_name = emp_name;  } } public class Emp_detail {  private static Emp Emp_detail(int id, String emp_name) {  return new Emp(id, emp_name);  }  public static void main(String[] args) {  int id = 21;  String name = 'Maddy';  Emp person_ = null;  person_ = Emp_detail(id, name);  } }>
Python
def main(): a = 10 # stored in stack p = None # declaring p variable p = 10 # allocating memory in heap del p # deleting memory allocation in heap p = [None] * 4 # array in heap allocation p = None # free heap return 0 if __name__ == '__main__': main()>
Javascript
// Define the Emp class with id and emp_name properties class Emp {  constructor(id, emp_name) {  this.id = id; // Initialize id  this.emp_name = emp_name; // Initialize emp_name  } } // Create an instance of the Emp class const person = new Emp(21, 'Maddy'); // Initialize person with id 21 and emp_name 'Maddy' console.log(person); // Output the person object to the console>

Im Folgenden sind die Schlussfolgerungen aufgeführt, zu denen wir nach der Analyse des obigen Beispiels ziehen werden:

  • Wenn wir mit der Ausführung des Have-Programms beginnen, werden alle Laufzeitklassen im Heap-Speicherbereich gespeichert.
  • Dann finden wir in der nächsten Zeile die main()-Methode, die zusammen mit allen ihren Grundelementen (oder lokalen) im Stapel gespeichert ist, und die Referenzvariable Emp vom Typ Emp_detail wird ebenfalls im Stapel gespeichert und zeigt auf das entsprechende Objekt im Heap-Speicher gespeichert.
  • Dann ruft die nächste Zeile den parametrisierten Konstruktor Emp(int, String) von main( ) auf und weist auch dem oberen Rand desselben Stapelspeicherblocks zu. Dadurch wird Folgendes gespeichert:
    • Die Objektreferenz des aufgerufenen Objekts des Stapelspeichers.
    • Der primitive Wert( Die Referenzvariable des Arguments String emp_name verweist auf die tatsächliche Zeichenfolge aus dem Zeichenfolgenpool im Heap-Speicher.
  • Dann ruft die Hauptmethode erneut die statische Methode Emp_detail() auf, für die eine Zuweisung im Stapelspeicherblock über dem vorherigen Speicherblock vorgenommen wird.
  • Die Referenzvariable des String emp_name-Arguments zeigt auf die tatsächliche Zeichenfolge aus dem Zeichenfolgenpool im Heap-Speicher.
  • Für das neu erstellte Objekt Emp vom Typ Emp_detail werden also alle Instanzvariablen im Heap-Speicher gespeichert.
  • Die Referenzvariable des String emp_name-Arguments zeigt auf die tatsächliche Zeichenfolge aus dem Zeichenfolgenpool im Heap-Speicher.

  • Bildliche Darstellung wie in Abbildung 1 unten dargestellt:

    Die Referenzvariable des String emp_name-Arguments zeigt auf die tatsächliche Zeichenfolge aus dem Zeichenfolgenpool im Heap-Speicher.
  • Abb.1

    Zentrieren eines Bildes in CSS

    Hauptunterschiede zwischen Stack- und Heap-Zuweisungen

    1. In einem Stack erfolgt die Zuweisung und Freigabe automatisch vom Compiler, während sie im Heap vom Programmierer manuell durchgeführt werden muss.
    2. Die Handhabung des Heap-Frames ist aufwendiger als die Handhabung des Stack-Frames.
    3. Das Problem der Speicherknappheit tritt eher im Stack auf, wohingegen das Hauptproblem im Heap-Speicher die Fragmentierung ist.
    4. Der Zugriff auf Stack-Frames ist einfacher als auf Heap-Frames, da der Stack über einen kleinen Speicherbereich verfügt und Cache-freundlich ist. Bei Heap-Frames, die über den gesamten Speicher verteilt sind, kommt es jedoch zu mehr Cache-Fehlern.
    5. Ein Stapel ist nicht flexibel, die zugewiesene Speichergröße kann nicht geändert werden, wohingegen ein Heap flexibel ist und der zugewiesene Speicher geändert werden kann.
    6. Der Zugriff auf den Heap dauert mehr als nur einen Stapel.

    Vergleichstabelle

    ParameterSTAPELHAUFEN
    BasicDer Speicher wird in einem zusammenhängenden Block zugewiesen.Der Speicher wird in beliebiger zufälliger Reihenfolge zugewiesen.
    Zuweisung und FreigabeAutomatisch durch Compileranweisungen.Handbuch vom Programmierer.
    KostenWenigerMehr
    ImplementierungEinfachHart
    ZugriffszeitSchnellerLangsamer
    HauptproblemMangel an GedächtnisSpeicherfragmentierung
    BezugsortExzellentAngemessen
    SicherheitThread-sicher, auf die gespeicherten Daten kann nur der Eigentümer zugreifenNicht Thread-sicher, die gespeicherten Daten sind für alle Threads sichtbar
    FlexibilitätFeste GrößeEine Größenänderung ist möglich
    DatentypstrukturLinearHierarchisch
    BevorzugtIn einem Array wird die statische Speicherzuweisung bevorzugt.In der verknüpften Liste wird die Heap-Speicherzuweisung bevorzugt.
    GrößeKleiner als Heap-Speicher.Größer als Stapelspeicher.