Haufen in Java:Dynamische Speicherzuweisung
In Java ist der Haufen ist ein Speicherbereich, der für die dynamische Speicherzuweisung verwendet wird. Hier werden alle Java -Objekte (Instanzen von Klassen) und Arrays gespeichert. Es ist * nicht * eine Datenstruktur wie die Heap-Datenstruktur, auf die Sie möglicherweise in Algorithmenkursen (Min-heap, max-heap) stoßen. Es ist entscheidend, diese Unterscheidung zu verstehen.
Schlüsselmerkmale des Java -Haufens:
1. Dynamische Zuweisung: Der Speicher für Objekte wird zur Laufzeit zugewiesen, nicht nach Bedarf kompilieren. Sie definieren die genaue Größe der Objekte im Voraus nicht vor.
2. gemeinsame Ressource: Der Java Heap ist eine gemeinsame Ressource für alle Threads innerhalb eines JVM. Dies bedeutet, dass mehrere Threads auf Objekte auf dem Haufen zugreifen und ändern können. Synchronisationsmechanismen (wie "synchronisierte" Blöcke, Schlösser usw.) sind erforderlich, um den gleichzeitigen Zugriff zu verwalten und Datenbeschäftigung zu verhindern.
3. Müllsammlung: Der Haufen wird vom Java Müllsammler (GC) verwaltet. Der GC holt den Speicher automatisch von Objekten zurück, die nicht mehr erreichbar sind (d. H. Nicht mehr von einem Teil des Programms verwiesen). Dadurch wird die Bedarf an manuellem Speichermanagement wie "malloc ()` und `Free ()` in Sprachen wie C ++.
4. Objektlebenszyklus: Objekte werden im Heap mit dem Schlüsselwort "New" erstellt. Sie wohnen im Haufen, bis sie unerreichbar werden und schließlich vom GC gesammelt werden.
5. Größe ist einstellbar: Die Größe des Heaps kann beim Starten der Java Virtual Machine (JVM) mit Befehlszeilenoptionen wie `-xms` (anfängliche Heap-Größe) und` -xmx` (maximale Heap-Größe) konfiguriert werden.
Wie der Haufen funktioniert:
1. Objekterstellung: Wenn Sie ein neues Objekt mit `New` erstellen, weist das JVM Speicher für das Objekt auf dem Heap zu. Die Felder des Objekts werden gemäß der Klassendefinition initialisiert.
`` `Java
Klasse myclass {
int x;
Zeichenfolge Name;
}
Hauptklasse Haupt {
public static void main (String [] args) {
Myclass obj =new myclass (); // Objekt wird auf dem Haufen erstellt
obj.x =10;
obj.name ="Beispiel";
}
}
`` `
In diesem Beispiel verteilt "New MyClass ()` Speicher auf dem Heap für ein Objekt vom Typ "myclass". Die Variable `obj` in` main` ist eine * Referenz * auf den Standort dieses Objekts auf dem Haufen. Es ist nicht das Objekt selbst, sondern ein Zeiger oder eine Adresse.
2. Objektreferenzen: Objekte werden durch Referenzen zugegriffen und manipuliert. Mehrere Referenzen können auf dasselbe Objekt auf dem Heap verweisen. Wenn alle Verweise auf ein Objekt verloren gehen (NULL werden, aus dem Zielfernrohr gehen usw.), wird das Objekt nicht erreichbar.
`` `Java
Myclass obj1 =new myclass ();
Myclass obj2 =obj1; // obj2 verweist nun das gleiche Objekt wie OBJ1
obj1 =null; // obj1 verweist das Objekt nicht mehr. Aber OBJ2 tut es immer noch.
// Das MyClass -Objekt ist nur für die Müllsammlung berechtigt, wenn OBJ2 ebenfalls nicht erreichbar wird.
`` `
3. Müllsammlungsprozess:
* Erreichbarkeitsanalyse: Das GC bestimmt, welche Objekte immer noch erreichbar sind, indem Referenzen aus Wurzelobjekten (z. B. lokale Variablen in aktiven Methoden, statischen Variablen) abverfolgt werden.
* Markierung: Erreichbare Objekte sind als "lebendig" markiert.
* Sweeping/Kompakting: Nicht erreichbare Objekte werden vom Haufen entfernt. Einige GC -Algorithmen verdichten auch den Haufen, um die Fragmentierung zu verringern.
4. Haufenfragmentierung: Im Laufe der Zeit kann der Haufen fragmentiert werden, was bedeutet, dass das freie Gedächtnis in kleinen, nicht zusammenhängenden Blöcken verstreut ist. Dies kann es schwieriger machen, große Objekte zuzuweisen. GC -Algorithmen enthalten häufig Verdichtungsphasen, um den freien Speicher zu konsolidieren.
5. Haufenstruktur (Generationshypothese): Moderne GCs teilen den Haufen häufig in Generationen auf der Grundlage der "Generationshypothese", die besagt, dass die meisten Objekte eine kurze Lebensdauer haben. Der Haufen ist typischerweise unterteilt in:
* junge Generation: Wo neue Objekte erstellt werden. Es ist weiter unterteilt in:
* Eden Space: Wo die meisten neuen Objekte ursprünglich zugewiesen werden.
* Überlebenderäume (S0, S1): Wird verwendet, um Objekte zu halten, die kleinere GC -Zyklen überlebt haben.
* alte Generation (angesehene Generation): Objekte, die in der jungen Generation mehrere GC -Zyklen überlebt haben, werden in die alte Generation gefördert.
! Wird verwendet, um Klassenmetadaten und andere statische Informationen zu speichern. ,
Der Generationsansatz ermöglicht es dem GC, seine Bemühungen auf die junge Generation zu konzentrieren, wo der größte Teil des Mülls erstellt wird.
Heap -Tuning:
Die Anpassung der Haufengröße kann die Anwendungsleistung erheblich beeinflussen.
* zu klein: Häufige GC -Zyklen, die zu einer Leistungsverschlechterung und potenziell "outofMemoryError" führen.
* zu groß: Längere GC -Pausen und wirken sich auf die Reaktionsfähigkeit aus.
Es ist wichtig, die GC -Aktivität zu überwachen und die Haufengröße anhand der Anwendungsanforderungen anzupassen. Tools wie Jconsole, VisualVM und Profiler können dabei helfen.
Schlüsselunterschiede vom Stapel:
* Heap: Wird zur dynamischen Zuordnung von Objekten verwendet. Über Threads geteilt. Von GC verwaltet.
* Stack: Wird zum Speichern lokaler Variablen und Methodenaufrufinformationen verwendet. Thread-spezifisch (jeder Thread hat seinen eigenen Stapel). Das Gedächtnis wird auf LIFO-Weise (Last-In, First-Out) zugeteilt und verhandelt.
Zusammenfassend:
Der Java -Heap ist der dynamische Speicherbereich, in dem sich Objekte befinden. Das Verständnis, wie die Haufen Funktionen, einschließlich seiner Struktur, der Rolle des Müllsammlers und potenziellen Themen wie Fragmentierung, entscheidend für das Schreiben effizienter und robuster Java -Anwendungen. Die richtige Haufengrößen- und GC -Tuning sind für die Optimierung der Leistung unerlässlich. Denken Sie daran, dass es sich um einen Speicherbereich handelt, der von der JVM und * nicht * eine Heap -Datenstruktur verwaltet wird.