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.

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:
- Heap
- Stapeln
- Code
- 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.
Die Variable x in m1 wird ebenfalls im Frame für m1 auf dem Stack erzeugt, wie in der folgenden Abbildung gezeigt.
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.
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.
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.
Die Referenzvariable ref wird im Stack innerhalb des Frames für m3 erstellt.
Der Zuweisungsoperator bewirkt, dass die Referenzvariable auf das Objekt im Heap verweist.
Sobald die Methode ihre Ausführung abgeschlossen hat, kehrt die Kontrolle zur aufrufenden Methode zurück, in diesem Fall zur Methode m2.
Der Frame für Methode m3 wird aus dem Stack entfernt.
Da die Referenzvariable nicht mehr auf das Objekt im Heap verweist, kann dieses Objekt der Garbage Collection unterzogen werden.
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.
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.
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.
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.
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.
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.


















