Skip to main content

Java Objekte leben auf dem Heap

Java hat eine interne Speicherverwaltung.
Eigentlich ist es nicht nur eine. Es sind mehrere.
 
Uns interessieren nur zwei.
Methoden und lokale Variablen werden auf dem Stack verwaltet.
Und die Speicherverwaltung für Java Objekte und den Instanzvariablen findet auf dem Heap statt.
 
Ja wieso braucht Java eigentlich zwei Speichersysteme?
 
Es ist ganz einfach.
Java Objekte werden an einem anderen Ort, gespeichert als Methoden oder lokale Variablen.

Denn ein Objekt umfasst meistens mehrere Variable.
Es ist somit ein ganz anderer Speicherbedarf notwendig.
Außerdem muss ein Objekt, unter Umständen, auch länger im Programm gehalten werden.
 
Okay und warum solltest du das wissen?

Stell dir vor, du schreibst ein Java Spiel.
Irgendeins bei dem du irgendwelche Vögel auf dem Bildschirm abschießen musst.
Jeder Vogel, welcher durch den Spieler getroffen wurde, verschwindet vom Bildschirm.
Und dafür kommt ein neuer Vogel.
 
Was meinst du?
Wenn der Vogel vom Bildschirm verschwindet, verschwindet er dann auch aus dem Speicher?
Kann es sein, dass sich der Speicher nach und nach füllt mit Vogel-Objekten, welche niemand braucht.
 
Und um diese Dinge zu vermeiden, solltest du wissen, wie Java Objekte speicherintern verwaltet werden.

Java Objekte existieren auf dem Heap

In einem anderen Beitrag habe ich schon einmal geschrieben, dass Methoden und lokale Variablen auf dem Stack gestapelt werden.
 
Für Java Objekte existiert eine andere Speicherverwaltung.
Und diese nennt sich Heap.
 
Bleiben wir beim Vogelspiel.
Im nachfolgenden Java Code habe ich, innerhalb der main Methode, ein „Vogelobjekt“ angelegt.


public class VogelSpiel {
	int vogelGroesse; // Größe in Pixel
 
 
	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel();
	}
}

Wir haben bereits geklärt, dass die main Methode auf dem Stack liegt.
Und lokale Variablen liegen ebenfalls auf dem Stack.
 
Aber in diesem Fall existiert noch ein Objekt.

Was ist mit diesem?
 
Ganz einfach.
Die Referenzvariable ist samt Main-Methode auf dem Stack.
Und diese verweist schließlich nur auf das Objekt.
 
Das eigentliche Objekt liegt auf dem Heap.

Java Objekte verweis Heap
 
Und nun?
Auf dem Heap wird dieses Objekt solange bereitgestellt, bis es nicht mehr gebraucht oder zerstört wird.
 

Wenn du Java Objekte aus dem Heap entfernen willst, schenke ihnen einfach keine Beachtung mehr.

Hört sich blöd an – Aber so ist es.
 
Im Vogelspiel wird es doch so sein:

  • Erster Vogel taucht auf.
  • Dieser wird abgeschossen.
  • Und dann kommt der nächste Vogel ins Spiel.

Das heißt.
Ich lege einen zweites „Vogelobjekt“ und eine zweite Referenzvariable an.


public class VogelSpiel {
	int vogelGroesse; // Größe in Pixel
 
 
	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel(); //Erstes Vogelobjekt
		VogelSpiel vogelZwei = new VogelSpiel(); //Zweites Objekt
 
	}
}
  • Die Referenzvariable „vogelEins“ verweist auf das erste Objekt.
  • Die Referenzvariable „vogelZwei“ verweist auf das zweite Objekt.

Java Objekte Zwei Verweise

Wenn der erste Vogel abgeschossen wurde, brauch ich diesen doch nicht mehr.
 
Und jetzt kann ich den Zeiger bzw. den Verweis auf das erste Objekt entfernen.
Dazu muss ich der Variablen „vogelEins“ den Wert der Variablen „vogelZwei“ zuweisen.
 
Zur Errinnerung:
Referenzvariablen speichern keine Zahl oder Ähnliches.
Sie speichern lediglich den Verweis auf ein Java Objekt.
 
Und wenn du der Variablen „vogelEins“ jetzt den Wert aus „vogelZwei“ zuweist, dann switchst du den Verweis um.
Java Objekte switch

Und Objekt 1 steht nun ohne Referenzvariable da.
Stattdessen verweisen jetzt zwei Variablen auf das zweite Objekt.
 
Und so würde das Ganze im Java Code aussehen:


public class VogelSpiel {
	int vogelGroesse; // Größe in Pixel
 
 
	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel(); //Erstes Vogelobjekt
		VogelSpiel vogelZwei = new VogelSpiel(); //Zweites Objekt
		vogelEins=vogelZwei; //Wert der Variablen vogelZwei wird vogelEins zugewiesen
	}
}

Okay, was passiert nun mit dem ersten Objekt?
 

Für Java Objekte ohne Verweis ist der Garbage Collector zuständig.

Und der Garbage Collector ist die Müllabfuhr von Java.
 
Dieses Feature hat nur eine Aufgabe.
Es sucht im ganzen Programm nach Objekten ohne Verweis und löscht diese aus dem Speicher.
Es würde somit das Objekt 1 vom Heap löschen und somit wieder Speicher freigeben.
 
Wie aktivierst du nun die Garbage Collection?
Gar nicht.
Das ganze passiert automatisch.
 
Der Garbage Collector erkennt automatisch:

  • „Ah, Objekt 1 vom Typ „VogelSpiel“ hat keinen Verweis.
  • Also schick ich das Ding ab in den Müll.
  • Und gebe wertvollen Speicher für neue Objekte frei.“

Cool, oder?
Aber was passiert mit den ganzen Instanzvariablen?
 

Instanzvariablen existieren solange, wie die dazu gehörigen Java Objekte.

Ich setze alles noch einmal auf Anfang.
 
Wir haben zwei Vogelobjekte, mit Referenzvariablen „vogelEins“ und „vogelZwei“.
 
VogelEins hat eine Größe von 22 Pixel.
VogelZwei hat eine Größe von 17 Pixel.

Java Objekte Instanzvariablen

Somit hat jedes Objekt seine eigene individuelle Instanzvariable.
 
Und so sieht der Code dazu aus.


public class VogelSpiel {
	int vogelGroesse; // Größe in Pixel
 
 
	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel(); //Erstes Vogelobjekt
		VogelSpiel vogelZwei = new VogelSpiel(); //Zweites Objekt
 
		vogelEins.vogelGroesse=22; // Vogel Eins mit 22px
		vogelZwei.vogelGroesse=17; // Vogel zwei mit 17 px
	}
}

Wenn ich jetzt den Zeiger von „vogelEins“ auf „vogelZwei“ switche, dann übertragen sich auch alle Werte der Instanzvariablen.
 
Aus Kontrollzwecken habe ich ein paar Bildschirmanzeigen in den Java Code einfließen lassen.
Klicke einmal „Run“ und du siehst das Ergebnis.


public class VogelSpiel {
	int vogelGroesse; // Größe in Pixel
 
 
	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel(); //Erstes Vogelobjekt
		System.out.println("VogelEins wurde angelegt");
		VogelSpiel vogelZwei = new VogelSpiel(); //Zweites Objekt
		System.out.println("VogelZwei wurde angelegt");
 
		vogelEins.vogelGroesse=22; // Vogel Eins mit 22px
		System.out.println("VogelEins hat eine Größe von: "+ vogelEins.vogelGroesse);
		vogelZwei.vogelGroesse=17; // Vogel zwei mit 17 px
		System.out.println("VogelZwei hat eine Größe von: "+ vogelZwei.vogelGroesse);
		 
		vogelEins=vogelZwei;
		System.out.println("VogelEins wurde auf VogelZwei umgeswicht");
		 
		System.out.println("Jetzt hat VogelEins die Größe: "+vogelEins.vogelGroesse);
	}
}

Und wenn die Java Objekte ohne Verweis zerstört werden.
Dann zerstört der Garbage Collector auch die dazu gehörigen Instanzvariablen.
 
Denn diese werden durch das Um-switchen ebenfalls überflüssig.

Java-Objekte-Instanzvariablen-Verweise

So und wenn du jetzt so ein Vogelspiel anlegst und dann circa 1000 Vogelobjekte durch den Bildschirm fliegen.
Und du durch eine Methode immer schön die Verweise abänderst, dann hältst du immer nur ein Objekt im Spiel.
 
Alle anderen Objekte werden durch den fehlenden Verweis zerstört.
 
Okay, du hast zwar nur ein Objekt.
Dennoch existieren irgendwann 1.000 Referenzvariablen.
 
Ist doch auch blöd, oder?
Lass uns das noch ändern.
 

Eine Referenzvariable kann auch auf verschiedene Objekte verweisen.

Ich stell mir das Ganze so vor:

  • Erstes Vogelobjekt wird mit einer Referenzvariablen angelegt.
  • Sobald das erste Objekt nicht mehr gebraucht wird, wird ein zweites Objekt angelegt.
    Jetzt wird aber keine zweite Referenzvariable angelegt.
  • Stattdessen verweist die ursprüngliche Variable vom ersten Java Objekt auf das zweite.
    Somit wird das erste Objekt unbrauchbar und es ist Futter für den Garbage Collector.

Java Objekte Garbage Collector

Besser, oder?
 
Und so geht’s.
Und zwar legst du immer wieder neue Objekte an.
Du legst aber keine neuen Referenzvariablen für diese Java Objekte an.


public class VogelSpiel {
	int vogelGroesse; // Größe in Pixel
 
 
	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel(); //Erstes Vogelobjekt
		vogelEins.vogelGroesse=22;
		System.out.println("Neuer Vogel mit "+vogelEins.vogelGroesse+" im Spiel.");
		System.out.println("Vogel tot");
		 
		vogelEins=new VogelSpiel(); //Zweites Vogelobjekt ohne neue Referenzvariable
		vogelEins.vogelGroesse=17;
		System.out.println("Neuer Vogel mit "+vogelEins.vogelGroesse+" im Spiel.");
		System.out.println("Vogel tot");
		 
		vogelEins=new VogelSpiel(); //Drittes Vogelobjekt ohne neue Referenzvariable
		vogelEins.vogelGroesse=5;
		System.out.println("Neuer Vogel mit "+vogelEins.vogelGroesse+" im Spiel.");
		System.out.println("Vogel tot");
	}
}

Somit brauchst du eine Variable, welche auf das aktuelle Objekt zeigt.
 
Alle Objekte, welche unbrauchbar sind, besitzen keinen Verweis.
Und diese werden vom Heap geschafft und es steht immer neuer Speicher zur Verfügung.
 
Zusammenfassung:

  • Java unterscheidet zwei wesentliche Speichersysteme.
  • Java Objekte werden im sogenannten Heap gespeichert.
    Instanzvariablen gehören zu den Objekten und werden ebenfalls dort verwaltet.
  • Methoden und deren lokalen Variablen befinden sich im Stack-Speicher.
  • Wenn du in der main-Methode ein Objekt anlegst, befindet sich die Referenzvariable im Stack und das Objekt im Heap.
  • Um den Heap immer wieder zu bereinigen, musst du nur die entsprechende Referenzvariable um-switchen.
    Alle Java Objekte ohne Verweis werden durch den Garbage Collector automatisch aus dem Heap entfernt.

Ähnliche Beiträge

Das Java Leben ist einfacher mit For-Schleife

Java For Schleife Aufbau

In einem anderen Artikeln habe ich bereits über Schleifen in Java gesprochen. In diesem Artikel möchte ich dir eine ganz besondere Schleife vorstellen. Warum ist diese so toll? Sie hat einen integrierten Schleifenzähler. Die Schleife zählt also bei jedem Durchlauf automatisch mit. Aber dazu gleich mehr…. Lass uns einmal so eine For Schleife anlegen.

Java Exklusives Oder – So nutzt du den Xor Operator

Java exklusives oder

In diesem Beitrag möchte ich dir den Xor Operator von Java vorstellen. Dieser Operator wird auch als ausschließendes oder exklusives Oder bezeichnet. Ein Beispiel: Was wilst du heute zum Mittag essen: Fleisch oder Fisch? Auf diese Frage gibt es nur eine Antwort. Es ist entweder Fisch oder Fleisch. Niemals beides. Das Eine schließt das andere […]

Java lernen von Kopf bis Fuß

Wenn du Java lernen möchtest, kannst du an meinem kostenlosen Java Kurs teilnehmen. Aber manch Einer hätte gern eine zweite Meinung. Und da bieten sich natürlich Java Bücher an. Eines dieser Java Bücher möchte ich dir jetzt vorstellen. Dieses Buch nennt sich „Java von Kopf bis Fuß“. Was kannst du von diesem Buch erwarten? Also […]

So kannst du Java installieren

Java installieren

Bevor du loslegst und deine ersten Java Programme schreibst, benötigst du die entsprechende Arbeitsumgebung. Du solltest also Java installieren. Und diese Arbeitsumgebung beinhaltet dann Bibliotheken für die einzelnen Java-Standard-Klassen, Dateien um deine Programme auszuführen. Dateien um deine Programme zu packen, Logische Verzeichnisstrukturen

So verwendest du Inkrement und Dekrement Operatoren in deinen Java Programmen

Java Operatoren

In diesem Beitrag geht es um Java Operatoren. Ich möchte dir gern zwei neue Operatoren vorstellen. Diese nennen sich Inkrement und Dekrement. Ja was heißt das? Inkrementieren bedeutet eine schrittweise Erhöhung einer Zahl. Und dementsprechend bedeutet Dekrementieren: Die schrittweise Verminderung einer Zahl. Wozu brauchst du das? Stell dir vor. Du bekommst eine Liste mit Namen […]

Ein Java Fenster erzeugen mit dem JFrame

Java-Fenster-erzeugen

Ein Java Fenster erzeugen mit Swing. Java Swing – was ist das? Zum Erstellen von grafischen Benutzeroberflächen, kurz GUI, bietet Java eine eigene Standardklasse an. Diese Klasse nennt sich Swing. Aus dieser Swing-Klasse heraus können Objekte erstellt werden. Diese Objekte lassen sich in vier verschiedene Kategorien einteilen. Fenster und Dialoge bilden das Grundgerüst einer grafischen […]

Java Vererbung findet auch zwischen Einkaufstüten und Polizeiautos statt

Java Vererbung

„Manchmal findet Java Vererbung auch zwischen Einkaufstüten und Polizeiautos statt“ Irrer Titel, oder? Aber mal Hand aufs Herz. Was haben eigentlich eine Einkaufstüte und ein Polizeiwagen gemeinsam? Ich verrate dir etwas: Du kannst die Verbindung nicht erkennen, denn ich habe dir nicht alles verraten. Es fehlt noch ein wichtiger Aspekt – eine Verbindung zwischen beiden. […]