Stapelspeicher und Heap-Speicher in Java
1. Einführung
Um eine Anwendung optimal auszuführen, teilt JVM den Speicher in Stapel- und Heapspeicher auf. Whenever we declare new variables and objects, call new method, declare a String or perform similar operations, JVM designates memory to these operations from either Stack Memory or Heap Space.
In diesem Tutorial werden diese Speichermodelle erläutert. Wir werden einige wichtige Unterschiede zwischen ihnen aufzeigen, wie sie im RAM gespeichert sind, welche Funktionen sie bieten und wo sie verwendet werden.
2. Stapelspeicher in Java
Stack Memory in Java is used for static memory allocation and the execution of a thread. Enthält primitive Werte, die für eine Methode spezifisch sind, und Verweise auf Objekte in einem Heap, auf die von der Methode verwiesen wird.
Der Zugriff auf diesen Speicher erfolgt in der Reihenfolge Last-In-First-Out (LIFO). Bei jedem Aufruf einer neuen Methode wird ein neuer Block über dem Stapel erstellt, der methodenspezifische Werte wie primitive Variablen und Verweise auf Objekte enthält.
Wenn die Ausführung der Methode abgeschlossen ist, wird der entsprechende Stack-Frame gelöscht, der Ablauf kehrt zur aufrufenden Methode zurück und Speicherplatz wird für die nächste Methode verfügbar.
2.1. Hauptmerkmale des Stapelspeichers
Abgesehen von dem, was wir bisher besprochen haben, sind im Folgenden einige andere Merkmale des Stapelspeichers aufgeführt:
-
Es wächst und schrumpft, wenn neue Methoden aufgerufen bzw. zurückgegeben werden
-
Variablen im Stapel sind nur so lange vorhanden, wie die Methode, mit der sie erstellt wurden, ausgeführt wird
-
Es wird automatisch zugewiesen und freigegeben, wenn die Ausführung der Methode abgeschlossen ist
-
Wenn dieser Speicher voll ist, löst Javajava.lang.StackOverFlowError aus
-
Der Zugriff auf diesen Speicher ist im Vergleich zum Heap-Speicher schnell
-
Dieser Speicher ist threadsicher, da jeder Thread in einem eigenen Stapel arbeitet
3. Heap Space in Java
Heap space in Java is used for dynamic memory allocation for Java objects and JRE classes at the runtime. Neue Objekte werden immer im Heap-Speicher erstellt und die Verweise auf diese Objekte werden im Stapelspeicher gespeichert.
Diese Objekte haben globalen Zugriff und können von überall in der Anwendung zugegriffen werden.
Dieses Speichermodell ist weiter in kleinere Teile unterteilt, die als Generationen bezeichnet werden. Dies sind:
-
Young Generation – Hier werden alle neuen Objekte zugewiesen und gealtert. Eine geringfügige Garbage-Auflistung tritt auf, wenn dies voll ist
-
Old or Tenured Generation – Hier werden lange überlebende Objekte gespeichert. Wenn Objekte in der jungen Generation gespeichert werden, wird ein Schwellenwert für das Alter des Objekts festgelegt. Wenn dieser Schwellenwert erreicht ist, wird das Objekt in die alte Generation verschoben
-
Permanent Generation – Dies besteht aus JVM-Metadaten für die Laufzeitklassen und Anwendungsmethoden
Diese verschiedenen Teile werden auch in diesem Artikel behandelt -Difference Between JVM, JRE, and JDK.
Wir können die Größe des Heapspeichers jederzeit gemäß unseren Anforderungen ändern. Weitere Informationen finden Sie unterlinked example article.
3.1. Hauptmerkmale des Java-Heapspeichers
Abgesehen von dem, was wir bisher besprochen haben, sind im Folgenden einige andere Merkmale des Heapspeichers aufgeführt:
-
Der Zugriff erfolgt über komplexe Speicherverwaltungstechniken wie Young Generation, Old oder Tenured Generation und Permanent Generation
-
Wenn der Heap-Speicher voll ist, löst Javajava.lang.OutOfMemoryError aus
-
Der Zugriff auf diesen Speicher ist relativ langsamer als der Stapelspeicher
-
Dieser Speicher wird im Gegensatz zum Stapel nicht automatisch freigegeben. Garbage Collector muss nicht verwendete Objekte freigeben, um die Effizienz der Speichernutzung zu erhalten
-
Im Gegensatz zu Stack ist ein Heap nicht threadsicher und muss durch ordnungsgemäße Synchronisierung des Codes geschützt werden
4. Beispiel
Analysieren wir anhand der bisherigen Erkenntnisse einen einfachen Java-Code und bewerten wir, wie der Speicher hier verwaltet wird:
class Person {
int pid;
String name;
// constructor, setters/getters
}
public class Driver {
public static void main(String[] args) {
int id = 23;
String pName = "Jon";
Person p = null;
p = new Person(id, pName);
}
}
Lassen Sie uns dies Schritt für Schritt analysieren:
-
Bei Eingabe dermain()-Methode wird ein Speicherplatz im Stapelspeicher erstellt, um Grundelemente und Referenzen dieser Methode zu speichern
-
Der Grundwert der Ganzzahlid wird direkt im Stapelspeicher gespeichert
-
Die Referenzvariablep of TypPerson will wird ebenfalls im Stapelspeicher erstellt, der auf das tatsächliche Objekt im Heap verweist
-
-
Der Aufruf des parametrisierten KonstruktorsPerson(int, String) vonmain() reserviert weiteren Speicher über dem vorherigen Stapel. Dies speichert:
-
Diethis Objektreferenz des aufrufenden Objekts im Stapelspeicher
-
Der Grundwertid inkt im Stapelspeicher
-
Die Referenzvariable vonString ArgumentpersonName, die auf die tatsächliche Zeichenfolge aus dem Zeichenfolgenpool im Heapspeicher verweist
-
-
Dieser Standardkonstruktor ruft die MethodesetPersonName()weiter auf, für die eine weitere Zuordnung im Stapelspeicher zusätzlich zu der vorherigen erfolgt. Dies speichert wiederum Variablen auf die oben beschriebene Weise.
-
Für das neu erstellte Objektp of TypPerson werden jedoch alle Instanzvariablen im Heapspeicher gespeichert.
Diese Zuordnung wird in diesem Diagramm erläutert:
5. Zusammenfassung
Bevor wir diesen Artikel abschließen, lassen Sie uns kurz die Unterschiede zwischen dem Stapelspeicher und dem Heap-Bereich zusammenfassen:
Parameter | Stapelspeicher | Haufenraum |
---|---|---|
Anwendung |
Der Stapel wird in Teilen einzeln während der Ausführung eines Threads verwendet |
Die gesamte Anwendung verwendet zur Laufzeit Heap-Speicherplatz |
Size |
Der Stapel hat je nach Betriebssystem Größenbeschränkungen und ist normalerweise kleiner als Heap |
Es gibt keine Größenbeschränkung für Heap |
Lager |
Speichert nur primitive Variablen und Verweise auf Objekte, die im Heap Space erstellt wurden |
Alle neu erstellten Objekte werden hier gespeichert |
Bestellung |
Der Zugriff erfolgt über das LIFO-Speicherzuweisungssystem (Last-In First-Out) |
Auf diesen Speicher wird über komplexe Speicherverwaltungstechniken zugegriffen, zu denen die junge Generation, die alte oder die dauerhafte Generation und die permanente Generation gehören. |
Life |
Der Stapelspeicher ist nur vorhanden, solange die aktuelle Methode ausgeführt wird |
Heap-Speicherplatz ist vorhanden, solange die Anwendung ausgeführt wird |
Effizienz |
Im Vergleich zu Heap ist die Zuweisung vergleichsweise viel schneller |
Im Vergleich zum Stapel langsamer zuzuordnen |
Allocation/Deallocation |
Dieser Speicher wird automatisch zugewiesen und freigegeben, wenn eine Methode aufgerufen bzw. zurückgegeben wird |
Heap-Speicherplatz wird zugewiesen, wenn neue Objekte von Gargabe Collector erstellt und freigegeben werden, wenn nicht mehr auf sie verwiesen wird |
6. Fazit
Stack und Heap sind zwei Möglichkeiten, wie Java Speicher zuweist. In diesem Artikel haben wir verstanden, wie sie funktionieren und wann sie für die Entwicklung besserer Java-Programme verwendet werden.
Weitere Informationen zur Speicherverwaltung in Java finden Sie unterthis article here. Wir haben auch den JVM Garbage Collector besprochen, der kurz inover in this article behandelt wird.