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

Der wichtige Unterschied zwischen Java Methoden

Java Methoden Unterschied

Jetzt machen wir Nägel mit Köpfen. Dieses Sprichwort stammt aus den Anfängen des Industriezeitalters. Denn früher wurden Nägel nicht industriell, sondern per Hand gefertigt. Und da kam es schon einmal vor, dass versehentlich Nägel ohne Kopf produziert wurden. Was blieb ist das Sprichwort „Nägel mit Köpfen“ Und dieses steht sinngemäß für eine schnelle, qualitativ hochwertige […]

Heap & Stack – Die Speicherverwaltung in Java

Java Speicher

Java nutzt eine interne Speicherverwaltung. Eigentlich sind es mehrere. Uns interessieren lediglich zwei. Da das Thema Speicherverwaltung recht umfangreich ist, habe ich dir im Folgenden einmal die wichtigsten Artikel zusammengestellt. Die zwei Speichersysteme von Java Java Methoden werden auf dem Stack gestapelt. Der Speicher auf dem Java Methoden zu Hause sind, nennt sich Stack Speicher. […]

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 […]

Java Übung 24 – So kannst du Kommazahlen runden

Java Übung runden

In dieser Java Übung möchte ich mit dir Zahlen runden. Ich bitte dich deshalb: Erstelle eine Klasse „RundenUebung“. Lege dann eine statische Methode rundeZahl() an. Diese erwartet zwei Parameter. Parameter 1 ist die Kommazahl, welche gerundet werden soll. Als zweiten Parameter wird eine ganze Zahl übergeben, welche die Nachkommastelle – bis auf welche letztlich gerundet […]

So kannst du Werte aus zwei oder mehreren Java Arrays verrechnen.

Java Arrays verrechnen

Wie kann man Werte aus zwei oder mehreren Java Arrays miteinander verrechnen? Zum Beispiel: Du möchtest alle Werte des ersten Arrays mit allen Werten des zweiten Arrays addieren Oder du möchtest die Summe aus beiden Arrays wissen und erst dann diese miteinander addieren. Was erwartet dich in diesem Beitrag? Zuerst werde ich dir zeigen, wie […]

Der bedeutende Unterschied zwischen Klassenvariablen und Instanzvariablen

Java Klassenvariablen

Bei der Java Programmierung unterscheidet man drei Arten von Variablen. Als erste Gruppe sind die lokalen Variablen zu nennen. Auf diese gehe ich in einem separaten Artikel ein. Mich interessieren die zwei anderen Variablentypen. Zum einen existieren Klassenvariablen. Und dann sind da noch die Instanzvariablen. Wo liegt der Unterschied? Instanzvariablen stehen einem Objekt zur Verfügung. […]

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 in den Java Klassen Attribute anlegen

Java Klassen Attribute

Die bisherigen Java Klassen in unserem Einführungsbeispiel besitzen noch keine Attribute. Das ändern wir und legen diese jetzt an. In diesem Beitrag erfährst du: Warum Variablen in deinen Klassen eine entscheidende Rolle spielen. Was es bedeutet eine Variable zu deklarieren. Wo du Attribute in den Java Klassen anlegen darfst und wo nicht. Wie du durch […]