Java Tutorial #19

Objekte löschen mit dem Garbage Collector

2018-12-12 | credit: Olivier/ adobe.stock

Thema in Kurzform

Der Garbage Collector löscht Objekte, die nicht mehr verwendet werden. Wann wird ein Objekt nicht mehr verwendet? Wenn keine Referenzvariable mehr auf ein Objekt zeigt, wird es gelöscht. In Java startet der Garbage Collector automatisch. Wir können ihn nicht selbst aktivieren.

Der Heap

Immer dann, wenn wir in Java Objekte erstellen, werden diese auf dem Heap gespeichert. Der Heap ist ein Speicherbereich, der Ihrem Java-Programm zugeordnet ist. Stellen Sie sich den Heap bildlich ruhig als eine Fläche oder einen Bereich vor, auf dem alle erzeugten Objekte gemeinsam leben. Immer dann, wenn ein neues Objekt erzeugt wird, landet es auf dem Heap. Ein Tummelplatz für Objekte!

Ein Objekt erhält auf dem Heap so viel Speicherplatz zugewiesen, wie es zum Existieren braucht. Je nach Klassendefinition unterscheiden sich die Objekte hinsichtlich ihres Speicherbedarfs auf dem Heap:

Java Objekte löschen der Heap

Wir erinnern uns an die Grundlagen der Objektorientierung: Objekte werden nicht in Variablen gespeichert, sondern die Sache verhält sich so, dass eine Referenzvariable auf ein Objekt verweist (Objektreferenz). 

Das Objekt liegt auf dem Heap. Wir können Objekte nicht direkt ansteuern, sondern ausschließlich über die Objektreferenz.

Referenzen haben immer dieselbe Größe. Objekte dagegen können in ihrer Größe stark variieren. Der Speicherplatz-Bedarf eines Objekts hängt von der jeweiligen Klassendefinition ab. Je komplexer die Klasse, desto mehr Speicher benötigt ein Objekt.

Hier könnte es problematisch werden: Der Heap ist nämlich nicht unendlich groß und je mehr Objekte auf ihm landen, desto geringer werden seine Speicherreserven. Ist der Heap voll, könnte das Programm einen OutOfMemoryError erleiden und abstürzen.

Garbage Collector

Damit es dazu aber nicht erst kommt, gibt es den garbage collector, der nicht mehr verwendete bzw. erreichbare Objekte vom Heap entfernt und so wieder Speicherplatz freigibt. Der garbage collector läuft automatisch im Hintergrund des Programms; wir können keinen direkten Einfluss auf ihn nehmen.

Aber wann ist ein Objekt nicht mehr erreichbar? Wann schmeißt also der Garbage Collector das nutzlos gewordene Objekt aus dem Heap? Hierfür gibt es eine klare und einfache Regel:

  • Ein Objekt ist dann nicht mehr erreichbar, wenn es keine Referenzvariable mehr gibt, die auf das Objekt verweist. Der Garbage Collector wird dieses verlorene Objekt dann vom Heap löschen.

Sehen wir uns das folgende Code-Beispiel an. Können Sie schon erkennen, in welcher Zeile welches Objekt für die garbage collection freigegeben wird?

public class Falke {

public static void main(String args[]){

    Falke f1 = new Falke(); //Erstes Falke-Objekt
    Falke f2 = new Falke(); //Zweites Falke-Objekt
    f2 = f1;
    }
}

Die Antwort lautet: In Zeile 7 wird das zweite Objekt der Klasse Falke zur Entfernung durch den garbage collector freigegeben.

Warum ist das so? 🤔

Vor Zeile 7 verweisen die beiden Referenzvariablen f1 und f2 auf jeweils eines der beiden Objekte. Beide Objekte haben also eine Verbindung zu einer Referenz. Doch In Zeile 7 geschieht es: Die Referenzvariable f2 verweist nun ebenfalls auf das erste Falke-Objekt (eine Referenz kann immer nur auf ein Objekt zeigen). Damit ist das zweite Falke-Objekt von seiner Referenz getrennt und "schwebt" ohne eine Verbindung zu irgendeiner Referenzvariablen im Heap herum. Das Todesurteil für dieses Objekt!

Es ist jetzt nur noch eine Frage der (sehr kurzen) Zeit, bis der garbage collector das Objekt aufsammelt und vom Heap löscht. Damit ist die Existenz dieses Objekts für alle Zeit zu Ende. Es wird gelöscht, der belegte Speicherplatz wieder frei.

Mit anderen Worten: Verliert ein Objekt die Verbindung zu einer Referenzvariablen, wird es der Sensenmann holen!

Sehen wir uns das Schicksal dieses verlorenen Objekts in einer Grafik an:

Java Objekt wird gelöscht

Gibt es keinen Weg, das Objekt doch noch zu retten? Nein: Denn weder können wir eine nachträgliche "Neu-Verbindung" des Objekts zu einer Referenz herstellen, noch können wir dem garbage collector sagen, er solle ein nutzlos gewordenes Objekt verschonen. Das alles ist auch gut so: Unser System wird automatisch aufgeräumt und kein Speicherplatz sinnlos verschwendet.

Ein Objekt wird natürlich auch dann nicht mehr erreichbar, wenn die entsprechende Referenzvariable, die auf das Objekt verweist, auf null gesetzt wird.

Falke f3 = new Falke();
f3 = null;

In Zeile 1 wird noch auf das eben neu erstellte Falke-Objekt verwiesen. In Zeile 2 aber wird die Referenzvariable auf null gesetzt, das heißt, sie verweist auf garnichts mehr. Damit ist die Verbindung zum Objekt verloren und es ist - sofern keine andere Referenzvariable darauf verweist - bereit für den garbage collector.

Spezielle Methoden

System.gc()

Die Klasse System stellt eine Methode namens System.gc() zur Verfügung. In der offiziellen Java API-Dokumentation heißt es zu dieser Methode: "Runs the garbage collector". Das ist aber nur die halbe Wahrheit. Die Methode macht lediglich einen Vorschlag, dass nun ein guter Zeitpunkt wäre, dass der garbage collector in Aktion tritt und damit die Speicherbereinigung erfolgt. Wir haben keine Garantie, dass die Methode auch tatsächlich den garbage collecotor zum Einsatz bringt. Wie wir oben schon gesagt haben: Wir haben auf das Verhalten des garbage collectors keinen direkten Einfluss.

finalize()

Diese Methode wird vom garbage collector aufgerufen, wenn das Objekt gelöscht wird. Sie ist von der Klasse Object geerbt und tut erst etwas, wenn wir sie überschreiben und mit Anweisungen ausprogrammieren:

// weiterer Klassencode

@Override
protected void finalize(){
    System.out.println("Objekt wurde vom GC vernichtet!");
}

// weiterer Klassencode

In unserem Beispiel wird, wenn ein Objekt der entsprechenden Klasse gelöscht wurde, die Konsolenmeldung "Objekt wurde vom GC vernichtet!" ausgegeben.

Werbung

Java lernen

Werde zum Java Profi!

PHP Lernen

Lerne serverbasierte Programmierung

JavaScript lernen

Skille dein Webcoding

FALCONBYTE.NET

Handmade with 🖤️

© 2018-2023 Stefan E. Heller

Impressum | Datenschutz | Changelog

Falconbyte Youtube Falconbyte GitHub facebook programmieren lernen twitter programmieren lernen discord programmieren lernen