Jetzt anmelden...

Name
Passwort
Registrieren

Java Tutorial #18

Objekte löschen mit dem Garbage Collector

Wir wissen, wie wir Objekte erstellen können. Aber wie werden wir sie wieder los?. Glücklicherweise übernimmt diese Aufgabe Java automatisch für uns. Java hat nämlich einen eingebauten garbage collector, der alle nicht mehr benötigten Objekte einsammelt und vernichtet.

Kommentare [0]

Stefan 12.12.2018

Infos zum Artikel

Kategorie Java
Autor Stefan
Datum 12.12.2018

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 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 Klase, 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 Sensemann holen!

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

Java Garbage Collector

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 Objekte 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 ausprogrammiern:

// 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.

Übungen

einfach

Wann wird ein Objekt vom Heap entfernt und vernichtet? .

Lösung ein-/ausblenden

mittel

Wieviele Objekte werden im folgenden Code erstellt und wieviele werden zur garbage collection freigegeben?

public class Tiger {

    public static void main(String args[]){

        Tiger t1, t2, t3;
        t1 = new Tiger();
        t2 = t1;
        t3 = new Tiger();
        t2 = null;
    }
}
Lösung ein-/ausblenden

schwer

Welche der folgenden Antwortmöglichkeiten den Code betreffend sind korrekt?

public class Fuchs {

    public static void main(String args[]) {
        Fuchs eins = new Fuchs();
        Fuchs zwei = new Fuchs();
        Fuchs drei = eins;
        eins = null;
        Fuchs vier = eins;
        drei = null;
        zwei = null;
        zwei = new Fuchs();
    }
}

A. Das Fuchs-Objekt von Zeile 3 wird gleich nach Zeile 6 für den garbage collector freigegeben.
B. Das Fuchs-Objekt von Zeile 3 wird gleich nach Zeile 8 für den garbage collector freigegeben.
C. Das Fuchs-Objekt von Zeile 3 wird gleich nach Zeile 12 für den garbage collector freigegeben.
D. Das Fuchs-Objekt von Zeile 4 wird gleich nach Zeile 9 für den garbage collector freigegeben.
E. Das Fuchs-Objekt von Zeile 4 wird gleich nach Zeile 11 für den garbage collector freigegeben.
F. Das Fuchs-Objekt von Zeile 4 wird gleich nach Zeile 12 für den garbage collector freigegeben.

Lösung ein-/ausblenden

Kommentar schreiben

Nur angemeldete Benutzer können kommentieren.

Alle Kommentare

Es gibt bislang noch keine Kommentare zu diesem Thema.

Objekte löschen

Wir wissen, wie wir Objekte erstellen können. Aber wie werden wir sie wieder los?

Einstieg Objektorientierung

Lernen Sie die Grundlagen der Objektorientierung

Arrays in Java

Arrays ermöglichen das Speichern von Daten in einer übergeordneten Datenstruktur

FALCONBYTE.NET

Handmade with 🖤️

© 2018, 2019 Stefan E. Heller

Impressum | Datenschutz

facebook programmieren lernen twitter programmieren lernen youtube programmieren lernen