Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Java

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Was ist Stack-Speicher?

In Java ist der Stack ein zusammenhängender Speicherbereich, der Methodenaufruf-Frames, lokale Variablen und Referenzvariablen hält. Jedes Mal, wenn eine Methode aufgerufen wird, wird ein neuer Frame auf den Stack gelegt. Der Stack-Speicher ist Last-In-First-Out (LIFO) organisiert, was bedeutet, dass der jüngste Aufruf der erste ist, der beim Methodenreturn entfernt wird.

Was ist Heap-Speicher?

Der Heap ist der Bereich, in dem Java-Objekte erstellt werden. Er hält alle Instanzen von Klassen und optional Referenzvariablen, die auf diese Objekte zeigen. Im Gegensatz zum Stack ist der Heap nicht an die Lebensdauer eines einzelnen Methodenaufrufs gebunden, was Objekten erlaubt, über den Gültigkeitsbereich hinaus zu bestehen, in dem sie erstellt wurden.

Speicherallokation in Java

Speicherallokation in Java bezeichnet den Prozess der Reservierung von virtuellem Speicher für Programmdaten. Variablen werden nicht bei der Deklaration allokiert; stattdessen wird eine Referenz erstellt. Wenn der new-Operator verwendet wird, allokiert die JVM Speicher auf dem Heap für das Objekt.

Java teilt den Speicher in vier verschiedene Abschnitte für effizientes Management:

  1. Heap
  2. Stack
  3. Code (Bytecode)
  4. Static (Klassendaten)

Lokale vs. Instanzvariablen

Instanzvariablen werden innerhalb einer Klasse, aber außerhalb jeder Methode deklariert:

class Student {
    int num; // Instanzvariable
    public void showData() {}
}

Lokale Variablen werden innerhalb einer Methode (oder als Methodenparameter) deklariert:

public void sum(int a) {
    int x = a + 3; // a und x sind lokale Variablen
}

Stack vs. Heap in Aktion

Lassen Sie uns ein Beispiel durchgehen, um zu veranschaulichen, wie Stack und Heap während Methodenaufrufen interagieren.

Angenommen, die main-Methode ruft m1() auf:

public void m1() {
    int x = 20;
}

Ein Frame für m1 wird auf den Stack gelegt. Die lokale Variable x wird in diesem Frame gespeichert.

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Wenn m1 m2(int b) aufruft, wird ein neuer Frame oben auf m1's Frame gelegt:

public void m2(int b) {
    boolean c;
}

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Ebenso ruft m2 m3() auf, was einen weiteren Frame erstellt:

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Innerhalb von m3 wird ein Account-Objekt auf dem Heap instanziiert, während seine Referenz ref auf dem Stack lebt:

class Account {
    int p;
    int q;
}
public void m3() {
    Account ref = new Account(); // zusätzlicher Code
}

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Die Referenzvariable ref wird in m3's Stack-Frame erstellt und zeigt auf das heap-allokierte Account-Objekt.

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Wenn m3 abgeschlossen ist, wird sein Stack-Frame entfernt, wodurch das Account-Objekt ohne Referenzen zurückbleibt. Es wird für Garbage Collection berechtigt.

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Derselbe Prozess wiederholt sich für m2 und m1, bis die Kontrolle an main zurückgegeben wird.

Objektreferenzen als Instanzvariablen

Betrachten Sie eine Klasse A, die eine Referenz auf eine Instanz von B hält:

public static void main(String[] args) {
    A parent = new A(); // zusätzlicher Code
}
class A {
    B child = new B();
    int e;
}
class B {
    int c;
    int d;
}

Hier wird die child-Referenz auf dem Heap als Teil des A-Objekts gespeichert und zeigt auf seine eigene B-Instanz.

Java Stack vs. Heap: Praktischer Leitfaden zur Speicherallokation

Wichtigste Erkenntnisse

Java

  1. Java Variablen und Literale: Umfassender Leitfaden
  2. Java Klassen und Objekte: Praktischer Leitfaden
  3. Java abstrakte Klassen und Methoden: Ein umfassender Leitfaden
  4. Java verschachtelte und innere Klassen meistern: Typen, Beispiele und Best Practices
  5. Java throw vs. throws: Exception Handling mit praktischen Beispielen meistern
  6. Java Annotation Types: Umfassender Leitfaden zu vordefinierten, benutzerdefinierten und Meta-Annotations
  7. Java Autoboxing und Unboxing meistern: Praktische Beispiele und Best Practices
  8. Java String-Ersetzung meistern: replace(), replaceAll() und replaceFirst() erklärt
  9. Java Methoden überschreiben: Superclass-Verhalten anpassen
  10. Java 10: Heap auf alternativen Speicher (NV-DIMM) allozieren – JEP 316