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

Achte bei Java Methoden stets auf die Wertübergabe

Java Methoden Wertübergabe

Ich lege gleich los…. Schau dir diesen Code einmal an. Welche Zahl wird wohl auf der Bildschirmanzeige zurückgegeben? public class MethodenWertUebergabe { static int verdoppele (int i){ i=i*2; return i; } public static void main(String[] args) { int i = 2; verdoppele(i); System.out.println(i); } }

So einfach lassen sich Java Strings umkehren

Java Strings umkehren

Kennst du noch das Lied „ANNA“ von Freundeskreis? Da hieß es: Du bist von hinten, wie von vorne A-N-N-A. Solche Namen oder Wörter, welche von hinten nach vorne gelesen – die gleiche Bedeutung haben, nennt man Palindrome. Anna, Ehe oder Ebbe sind recht kurze Palindrome. Aber auch längere zusammengesetzte Palindrome kennt die deutsche Sprache: Regallager […]

Java lernen – 10 nützliche Tipps für Java Anfänger

Java Lernen Anfänger

Wenn du die Programmiersprache Java lernen möchtest, bist du hier prinzipiell erst einmal richtig. Und wenn du es wirklich ernst meinst und in die Java Programmierung einsteigen möchtest, solltest du auch meinen kostenlosen Java Kurs beanspruchen. Wenn du dabei bist, bekommst du: Eine Lektion pro Woche zu den Basics. Hier geht es um die ersten […]

Die sechs Bestandteile von Java Methoden

Java Methoden Bestandteile

Java Methoden hauchen deinem Java Programm Leben ein. Ohne eine Methode würde deine Java Klasse ein starres Konstrukt sein. Deine Objekte hätten Eigenschaften. Aber sie könnten nichts machen. Und das wäre eine trostlose Welt. Java Methoden sorgen also dafür, dass Objekte interagieren. Methoden bestehen aus bestimmten Bausteinen. Und diese Bausteine bestimmen, was die Methode darf […]

Java Vererbung – Die Hierarchien richtig planen

Java Vererbung Hierarchien

Java Vererbung hat nichts mit Biologie zu tun. Die Genetik besagt, dass bestimmte Merkmalsausprägungen von den Eltern auf die Kinder übergehen. Solche Merkmalsausprägungen sind: die Hautfarbe die Haarfarbe die spezifische Größe und weitere körperliche Merkmale. Und in Java – was ist da Vererbung? Lass es uns herausfinden. Was erwartet dich in diesem Beitrag? Zuerst schauen […]

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 Übung 21 – Bestimme die Anzahl der Tage

Java Übung Tage

In dieser Java Übung möchte ich, dass du eine Methode schreibst, welche zwei Zahlen entgegennimmt. Und zwar soll die erste Zahl das Jahr sein. Die zweite Zahl soll eine Monatsangabe (1-12) repräsentieren. Was soll die Methode dann machen? Die Methode soll dir die Anzahl der Tage des jeweiligen Monats zurückgeben. Achte auf Schaltjahre.

So unterstützen dich Java Vererbungstabellen beim Entwurf

Java Vererbungstabellen

Bei der Java Vererbung gibt es zwei Klassenarten bzw. -stufen. Die Superklassen, welche einen allgemeinen Typen darstellen Und die spezielleren Unterklassen, welche die Superklasse um bestimmte Funktionen erweitern. Jetzt ist dieses ganze „Der-erbt-von-dem-Konzept“ mitunter sehr schwierig darzustellen. Zum Beispiel in einem Werkzeugkoffer. In einem Werkzeugkoffer befinden sich sämtliche Werkzeuge, von Säge bis Bohrmaschine. Wie machst […]

Drei Möglichkeiten um Java Objekte zu zerstören

Java Objekte zerstören

Java Objekte leben genau solange, wie eine Referenzvariable auf sie zeigt. Wenn dieser Zeiger nicht mehr existiert, wird dieses Objekt aufgeben. Und wenn dieses Objekt erst einmal aufgegeben wurde, dann kommt der Garbage Collector und entsorgt dieses. Aber wie kannst du nun am Sinnvollsten Objekte aufgeben? Lass es uns herausfinden.

So kannst du deine Java Methoden ausführen

Java Methoden ausführen

Du hast die ersten Java Methoden erstellt. Doch wie greifst du jetzt auf diese zu? Wie kannst du diese Methoden in einer anderen Klassen aufrufen? Welcher Unterschied, hinsichtlich des Methodenaufrufes, besteht eigentlich zwischen deinen Java Methoden? Diese Fragen möchte ich gern in diesem Beitrag beantworten. Gehen wir dazu in den Garten und schauen uns Blumen […]