Speicherverwaltung in Java

โšก Intelligente Zusammenfassung

Speicherverwaltung in Java erklรคrt, wie die JVM den Laufzeitspeicher in Stack, Heap und Codeund statische Bereiche, wie Objektverweise wรคhrend Methodenaufrufen flieรŸen und wie der Garbage Collector nicht erreichbare Objekte freigibt, damit Anwendungen stabil bleiben und frei von Speicherlecks sind.

  • ๐Ÿง  JVM-Speicherlayout: Java Der Speicher ist aufgeteilt in Heap fรผr Objekte, Stack fรผr Methodenrahmen und lokale Variablen sowie dedizierte Bereiche fรผr Bytecode und statische Daten.
  • ๐Ÿ“š Stack vs Heap: Stack-Frames folgen der LIFO-Reihenfolge (Last-In-First-Out) und speichern Primitive und Referenzen, wรคhrend der Heap jedes Objekt enthรคlt, das mit dem new-Operator erstellt wurde.
  • โ™ป๏ธ Mรผllabfuhr: Der Mรผllsammler tracks-Erreichbarkeit รผber Referenzketten und automatische Speicherfreigabe von Objekten, die kein Thread erreichen kann.
  • โœ… Moderne Sammler: In der Produktion werden zunehmend G1, ZGC und Shenandoah fรผr die Sammlung von Speicher mit geringen Pausen รผber mehrere Gigabyte groรŸe Heaps hinweg eingesetzt.
  • ๐Ÿงช Praxisbeispiel: Eine schrittweise Erlรคuterung der Student-Klasse zeigt, wann Referenzen fรผr die Sammlung in Frage kommen und wie das Setzen von Referenzen auf Null das zugrunde liegende Objekt freigibt.

Speicherverwaltung in Java

Was ist Stack-Speicher in Java?

Stack-Speicher in Java Der Stack ist der Bereich des JVM-Speichers, der Methodenframes, lokale Variablen und Referenzvariablen fรผr jeden Thread speichert. Der Zugriff auf den Stack erfolgt stets in LIFO-Reihenfolge (Last-In-First-Out), sodass die zuletzt aufgerufene Methode oben liegt und ihre lokalen Variablen zusammen mit dem Methodenframe auf den Stack gelegt bzw. von diesem entfernt werden.

Jeder Faden im Java Die virtuelle Maschine verfรผgt รผber einen eigenen Stack, der Methodenaufrufe systembedingt isoliert und threadsicher macht. Primitive lokale Datentypen wie int, boolean und double befinden sich direkt im Frame, wรคhrend Objektverweise auf dem Stack auf Objekte verweisen, die im Heap allokiert sind.

Was ist Heap-Speicher? Java?

Der Heap-Speicher ist der gemeinsam genutzte JVM-Bereich, der alle Daten enthรคlt. Java Objekte und Arrays, die mit dem `new`-Operator erstellt wurden, sowie alle Referenzvariablen, die zu diesen Objekten als Instanzfelder gehรถren. Im Gegensatz zum Stack wird der Heap von allen Threads gemeinsam genutzt, weshalb der Zugriff auf Objekte hรคufig eine Synchronisierung erfordert.

Der Heap ist der Bereich, der vom Garbage Collector verwaltet wird. Moderne HotSpot-JVMs unterteilen den Heap in eine Young Generation fรผr kurzlebige Objekte und eine Old Generation fรผr langlebige Objekte, wobei Klassenmetadaten in einem separaten nativen Bereich namens Metaspace gespeichert werden.

Speicherzuordnung in Java

Speicherzuordnung in Java Das ist der Prozess, durch den die JVM wรคhrend der Programmausfรผhrung virtuelle Speicherbereiche fรผr Variablen und Instanzen von Klassen und Strukturen reserviert. Der Speicher wird bei der Deklaration nicht einem Objekt zugewiesen; es wird lediglich eine Referenz erstellt. Die eigentliche Objektzuweisung erfolgt รผber den `new`-Operator, sodass jedes Objekt auf dem Heap gespeichert wird.

Das Java Die Speicherverwaltung ist in folgende Abschnitte unterteilt:

  1. Heap
  2. Stapeln
  3. Code
  4. Statisch

Diese Aufteilung des Speichers ist fรผr ein effektives Laufzeitmanagement erforderlich.

  • Das Code Dieser Abschnitt enthรคlt Ihre kompilierte Bytecode.
  • Das Stapeln Abteilungsgeschรคfte Methoden, lokale Variablen und Referenzvariablen.
  • Das Heap Abschnitt enthรคlt Objekte und kรถnnen auch Referenzvariablen enthalten, die als Instanzfelder gespeichert sind.
  • Das Statisch Abschnitt hรคlt statische Daten und statische Methoden Wird von allen Instanzen gemeinsam genutzt.

Unterschied zwischen lokaler und Instanzvariable

Das Verstรคndnis dafรผr, wo die verschiedenen Variablentypen in der JVM gespeichert sind, hilft, das Verhalten von Stack und Heap zu erklรคren. Instanzvariable wird deklariert innerhalb einer Klasse, aber auรŸerhalb einer Methodeund es lebt auf dem Haufen als Teil seines Objekts weiter.

class Student{ 
int num; // num is instance variable 
public void showData{}

A lokale Variable wird deklariert innerhalb einer Methode, einschlieรŸlich Methodenargumenteund befindet sich im Stack innerhalb des aktiven Frames.

public void sum(int a){

int x = a + 3;

// a, x are local variables

}

Unterschied zwischen Stack und Heap

Stack und Heap lรถsen unterschiedliche Probleme innerhalb der JVM. Der Stack ermรถglicht jedem Thread eine schnelle, deterministische Speicherzuweisung fรผr kurzlebige Daten, die an den Gรผltigkeitsbereich einer Methode gebunden sind, wรคhrend der Heap einen gemeinsamen Bereich fรผr langlebige Objekte bereitstellt, auf den jeder Thread zugreifen kann. Das kurze Video unten fasst den Unterschied zusammen, bevor die anschlieรŸende Erlรคuterung folgt.

Klicken Sie auf werden auf dieser Seite erlรคutert wenn das Video nicht zugรคnglich ist

Um zu sehen, wie Stack und Heap zusammenarbeiten, betrachten wir eine Hauptmethode, die die Methode m1 aufruft.

public void m1{
int x = 20;
}

Im JVM-Stack wird ein Frame fรผr die Methode m1 erstellt.

Java Stapel und Haufen

Die Variable x in m1 wird ebenfalls im Frame fรผr m1 auf dem Stack erzeugt, wie in der folgenden Abbildung gezeigt.

Java Stapel und Haufen

Die Methode m1 ruft dann die Methode m2 auf. Im Stack wird ein neuer Frame fรผr m2 รผber dem Frame fรผr m1 erstellt.

Java Stapel und Haufen

Java Stapel und Haufen

Die lokalen Variablen b und c werden ebenfalls innerhalb des Frames fรผr m2 auf dem Stack erstellt.

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

Als Nรคchstes ruft m2 die Methode m3 auf. Auch hier wird ein Frame fรผr m3 oben auf dem Stack erstellt, wie unten dargestellt.

Java Stapel und Haufen

Java Stapel und Haufen

Nehmen wir nun an, die Methode m3 erstellt ein Objekt der Klasse Account, die zwei Eigenschaften besitzt. Instanzvariablen int p und int q.

class Account {
    int p;
    int q;
}

Hier ist der Code fรผr die Methode m3.

public void m3(){
    Account ref = new Account();
    // more code
}

Die Anweisung new Account() erzeugt ein Objekt vom Typ Account auf dem Heap.

Java Stapel und Haufen

Die Referenzvariable ref wird im Stack innerhalb des Frames fรผr m3 erstellt.

Java Stapel und Haufen

Der Zuweisungsoperator bewirkt, dass die Referenzvariable auf das Objekt im Heap verweist.

Java Stapel und Haufen

Sobald die Methode ihre Ausfรผhrung abgeschlossen hat, kehrt die Kontrolle zur aufrufenden Methode zurรผck, in diesem Fall zur Methode m2.

Java Stapel und Haufen

Der Frame fรผr Methode m3 wird aus dem Stack entfernt.

Java Stapel und Haufen

Da die Referenzvariable nicht mehr auf das Objekt im Heap verweist, kann dieses Objekt der Garbage Collection unterzogen werden.

Java Stapel und Haufen

Sobald die Methode m2 beendet ist, wird sie vom Stack entfernt und alle ihre Variablen sind nicht mehr verfรผgbar. Dasselbe geschieht mit der Methode m1, und schlieรŸlich kehrt die Programmausfรผhrung zur Hauptmethode zurรผck.

Was passiert, wenn ein Objekt eine andere Referenz als Instanzvariable enthรคlt?

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

In diesem Fall befindet sich die Referenzvariable child auf dem Heap als Teil des Objekts A und verweist ihrerseits auf ihr eigenes Objekt B, wie unten dargestellt.

Java Stapel und Haufen

Was ist Garbage Collection in Java?

Garbage Collection in Java Die automatische Speicherverwaltung der JVM (Java Virtual Machine) erfolgt durch den Garbage Collector. Dieser findet Objekte, auf die keine Referenzen mehr zugegriffen werden kรถnnen, und gibt deren Speicher frei. Die dynamische Speicherzuweisung erfolgt รผber den `new`-Operator, und der Speicher bleibt so lange reserviert, bis das Programm keine Referenz mehr auf das Objekt hรคlt.

Wenn keine Referenzen mehr vorhanden sind, wird das Objekt nicht mehr benรถtigt und der von ihm belegte Speicher kann freigegeben werden. Es besteht keine explizite Notwendigkeit, ein Objekt zu zerstรถren, weil Java Die Speicherfreigabe erfolgt automatisch รผber den Garbage Collector.

Die dahinterstehende Technik ist bekannt als MรผllsammlungProgramme, die keinen Speicher freigeben kรถnnen, stรผrzen schlieรŸlich ab, wenn kein Speicher mehr freigegeben werden kann. Solche Programme gelten als ineffizient. Speicherlecks. Garbage Collection in Java lรคuft automatisch รผber die gesamte Laufzeit des Programms hinweg, wodurch der Aufwand fรผr die manuelle Freigabe entfรคllt und das Risiko von Datenlecks verringert wird.

In C hingegen ist der Programmierer fรผr die Freigabe des dynamisch allokierten Speichers mittels der Funktion `free()` verantwortlich. Hier liegt das Problem. Java Das Speichermanagement bietet einen deutlichen Vorteil.

Moderne HotSpot JVMs enthalten mehrere Garbage Collector, die fรผr unterschiedliche Arbeitslasten optimiert sind. Der standardmรครŸige G1 Garbage Collector zielt auf einen ausgewogenen Durchsatz und kurze Pausenzeiten bei Heaps im Gigabyte-Bereich ab. ZGC und Shenandoah hingegen streben Pausen im Submillisekundenbereich bei sehr groรŸen Heaps an, was sie zu einem leistungsstarken Garbage Collector macht.tracfรผr latenzkritische Dienste geeignet. Die Auswahl des richtigen Datensammlers und die Anpassung der GrรถรŸen von Young Generation, Old Generation und Metaspace sind eine Kernkompetenz fรผr Java Performancearbeit.

Hinweis: Alle Objekte werden im Heap-Speicherbereich erstellt, der vom Garbage Collector verwaltet wird.

Beispiel: So lernen Sie den Garbage Collector-Mechanismus in Java

Diese Schritt-fรผr-Schritt-Anleitung zeigt, wann Referenzen innerhalb eines einfachen Programms fรผr die automatische Speicherbereinigung (Garbage Collection) in Frage kommen.

Schritt 1) Kopieren Sie den folgenden Code in einen Editor.

class Student{
int a;
int b;
  public void setData(int c,int d){
    a=c;
    b=d;
  }
  public void showData(){
    System.out.println("Value of a = "+a);
    System.out.println("Value of b = "+b);
  }
  public static void main(String args[]){
    Student s1 = new Student();
    Student s2 = new Student();
    s1.setData(1,2);
    s2.setData(3,4);
    s1.showData();
    s2.showData();
    //Student s3;
    //s3=s2;
    //s3.showData();
    //s2=null;
    //s3.showData();
    //s3=null;
    //s3.showData();
  }
}

Schritt 2) Speichern, kompilieren und fรผhren Sie den Code aus. Wie im Diagramm dargestellt, werden zwei Objekte und zwei Referenzvariablen erstellt.

 Garbage-Collector-Mechanismus

Schritt 3) Entfernen Sie die Kommentarzeichen in den Zeilen 20, 21 und 22. Speichern, kompilieren und fรผhren Sie den Code aus.

Schritt 4) Wie im folgenden Diagramm dargestellt, verweisen nun zwei Referenzvariablen auf dasselbe Objekt.

Garbage-Collector-Mechanismus

Schritt 5) Entfernen Sie die Kommentarzeichen in den Zeilen 23 und 24. Speichern, kompilieren und fรผhren Sie den Code aus.

Schritt 6) Wie unten gezeigt, wird s2 zu null, aber s3 zeigt immer noch auf das Objekt, sodass das Objekt noch nicht fรผr die Garbage Collection geeignet ist.

 Garbage-Collector-Mechanismus

Schritt 7) Entfernen Sie die Kommentarzeichen in den Zeilen 25 und 26. Speichern, kompilieren und fรผhren Sie den Code aus.

Schritt 8) Zu diesem Zeitpunkt verweist keine Referenz mehr auf das Objekt, sodass es von der Garbage Collection freigegeben wird. Die Garbage Collection entfernt es aus dem Speicher, und es gibt keine Mรถglichkeit, es wiederherzustellen.

 Lernen Sie Garbage Collector

Wie man ein Objekt lรถscht in Java?

Java Da es keinen manuellen Lรถschoperator gibt, besteht der Standardansatz darin, jede Referenz auf das Objekt zu entfernen, damit der Garbage Collector es freigeben kann.

1) Um ein Objekt fรผr die automatische Speicherbereinigung (Garbage Collection) freizugeben, weisen Sie jeder Referenzvariablen, die auf dieses Objekt verweist, den Wert null zu.

2) Primitive Datentypen sind keine Objekte, daher kann ihnen nicht der Wert null zugewiesen werden. Ihr Speicherplatz wird automatisch freigegeben, wenn der umgebende Stack-Frame entfernt wird.

So lรถschen Sie ein Objekt in Java

Hรคufig gestellte Fragen

Der Stack speichert Methodenrahmen, lokale Variablen und Referenzen pro Thread in LIFO-Reihenfolge (Last-In-First-Out). Der Heap speichert alle mit `new` erstellten Objekte und wird von allen Threads gemeinsam genutzt; daher wird er vom Garbage Collector verwaltet.

Der Garbage Collector durchlรคuft Referenzketten von GC-Wurzeln wie aktiven Threads und statischen Feldern. Jedes Objekt, das von einer Wurzel aus nicht erreichbar ist, gilt als nicht erreichbar und kann im nรคchsten Zyklus freigegeben werden.

Die Young Generation speichert kurzlebige Objekte in den Eden- und Survivor-Speicherbereichen. Die Old Generation speichert Objekte, die mehrere Sammlungen รผberdauern. Der Metaspace ist ein nativer Speicherbereich, der Klassenmetadaten speichert und den รคlteren PermGen ersetzt hat. Java 8.

G1 ist der Standard und eignet sich fรผr die meisten Workloads auf Multi-Gigabyte-Heaps. ZGC und Shenandoah zielen auf Pausen im Submillisekundenbereich auf sehr groรŸen Heaps ab und sind eine gute Wahl fรผr latenzempfindliche Dienste, die auf solchen Systemen laufen. Java 17 oder hรถher.

Setzen Sie alle Referenzen auf das Objekt auf null oder lassen Sie die Referenzen ihren Gรผltigkeitsbereich verlieren, sobald ihre Stack-Frames entfernt werden. Sobald keine aktive Referenz mehr auf das Objekt zugreift, gibt der Garbage Collector den Heap-Speicher frei.

Ja. KI-gestรผtzte Optimierungstools analysieren GC-Protokolle, Speicherbelegungsraten und Pausenhistogramme, um Heap-GrรถรŸen, Collector-Flags und Young-Generation-Verhรคltnisse zu empfehlen. Sie verkรผrzen den Feedback-Zyklus im Vergleich zur manuellen Optimierung, insbesondere bei G1-, ZGC- und Shenandoah-Workloads.

KI-basierte Observability-Plattformen erfassen Heap-Dumps und Live-Metriken und clustern anschlieรŸend die Graphen der gespeicherten Objekte, um verdรคchtige Klassen und Referenzketten zu kennzeichnen. Dadurch werden potenzielle Lecks schneller als bei einer manuellen Heap-Analyse aufgedeckt und Teams kรถnnen die Ursache direkt im Produktivbetrieb ermitteln.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: